swift-compiler

Swift compiler speed with array concatenation


I'd like to understand what could be the least painful way for programmer and compiler to get the following code to compile in a reasonable time

extension Array {
    func unflat() -> [[Element]] {
        return self.map{[$0]}
    }
}

let EnglishLayout: [[String]] = [
    ["1", "!"],
    ["2", "@"],
    ["3", "#"],
    ["4", "$"],
    ["5", "%"],
    ["6", "^"],
    ["7", "&"],
    ["8", "*"],
    ["9", "(", "-", "_"],
    ["0", ")", "=", "+"],
    ["Q", "`", "~"]
] + ["W", "E", "R", "T", "Y", "U", "I"].unflat() + [
    ["O", "[", "{"],
    ["P", "]", "}"],
] + ["A", "S", "D", "F", "G", "H", "J"].unflat() + [
    ["K", ";", ":"],
    ["L", "'", "\""],
    ["\\", "|"],
] + ["Z", "X", "C", "V", "B", "N", "M"].unflat() + [
    [",", "<"],
    [".", ">"],
    ["/", "?"],
]

It simply fails to compile for me with 'too complex type expression'

I added the analyze flag to build settings and commented out the last two parts -Xfrontend -warn-long-expression-type-checking=100 enter image description here Apparently the Swift compiler is too intelligent to choose the path of the least resistance and simply concatenate the arrays as instructed by the programmer with an explicit type declaration. Coming from Dart and TypeScript it's not at all obvious to me how to tackle issues like this.


Solution

  • Unfortunately, I can't provide any explanation on why the compiler isn't able to evaluate this fairly simple array. However, the swift compiler is often overwhelmed by any big / slightly complex array expressions. I see, therefore, three possible solutions for your case:

    1. Write the contents to a auxiliary file and read it from there, for example in JSON or CSV format
    2. manually unravel the contents (i.e. don't write ... + ["A", "B"].unflat() but [["A"], ["B"]]
    3. Use a closure to initialize the array like so:
    let EnglishLayout: [[String]] = {
        var layout: [[String]] = [
            ["1", "!"],
            ["2", "@"],
            ["3", "#"],
            ["4", "$"],
            ["5", "%"],
            ["6", "^"],
            ["7", "&"],
            ["8", "*"],
            ["9", "(", "-", "_"],
            ["0", ")", "=", "+"],
            ["Q", "`", "~"]
        ]
        layout += ["W", "E", "R", "T", "Y", "U", "I"].unflat()
        layout += [
            ["O", "[", "{"],
            ["P", "]", "}"]
        ]
        layout += ["A", "S", "D", "F", "G", "H", "J"].unflat()
        layout += [
            ["K", ";", ":"],
            ["L", "'", "\""],
            ["\\", "|"]
        ]
        layout += ["Z", "X", "C", "V", "B", "N", "M"].unflat()
        layout += [
            [",", "<"],
            [".", ">"],
            ["/", "?"]
        ]
        return layout
    }()