
Go Home Swift Compiler, You’re Drunk - micahalles
https://spin.atomicobject.com/2016/04/26/swift-long-compile-time/
======
jopamer
(FWIW, I just pushed a fix for this bug.)

EDIT: To be clear, addressing these kinds of issues is something we've been
aggressively pursuing for Swift 3, and will continue to do so.

~~~
kristianp
Nice commit message:

[https://github.com/apple/swift/commit/2cdd7d64e1e2add7bcfd54...](https://github.com/apple/swift/commit/2cdd7d64e1e2add7bcfd5452d36e7f5fc6c86a03)

------
kenferry
The problem, by the way, is that the use of nested literals (string and
dictionary, here) causes the compiler to do a very large search to resolve the
types. A quoted string, e.g. "foo", could be any type that conforms to
StringLiteralConvertible. It's evaluating all permutations of potential type
assignments to each literal that appears.

I thought they fixed this, though. I filed it for Array<Array<Int>> long ago,
and they patched that case.
[https://twitter.com/kongtomorrow/status/565844856690339841](https://twitter.com/kongtomorrow/status/565844856690339841)

~~~
draw_down
Jeez. Is there some sort of hint to indicate that a string is just a string?
Otherwise that seems like it will always be slow.

~~~
rsfinn
Well, yes; it's called type annotation (as noted in comments both here and at
the original article). Telling the compiler it's "just a String" (or more
precisely a dictionary containing strings) cuts the compile time to 100ms.

Yes, the type inference in this case could use some improvement -- maybe guess
the simplest possible interpretation first, and search the space of
alternatives in the background, assuming there's a mechanism to go back for a
do-over if any are eventually found...?

~~~
outworlder
The background check would still take 12 hours in this case.

~~~
goldenkey
Unless you solve the [1] Entscheidungsproblem, taking two symbolic expressions
(ie. two complex types) and finding if they are equal is unsolved and thought
to be equivalent to solving the halting problem. [2] SAT style solvers are the
best we have at the moment. Heuristics can be improved, of course. But we are
really just shooting for common use cases in a turing complete language. Which
really means...in a universe of infinite code and types that can be created -
we are choosing to speed up our compiler for certain ones at the dismay of
others. Overall though, since Swift is going to be used for making mostly
trivial mobile apps, I don't really hold the academic high hat over it, let it
take all the assumptions it wants.

[1]
[https://en.wikipedia.org/wiki/Entscheidungsproblem](https://en.wikipedia.org/wiki/Entscheidungsproblem)

[2]
[https://en.wikipedia.org/wiki/Boolean_satisfiability_problem](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem)

------
coldcode
How many other two year old languages are there in large scale use? It's not
surprising there are issues in compiling things. I've used so many languages
early on since I started in the 80's and you can always find some syntax the
compiler doesn't like. Given the pedigree of the people building Swift who
also built the entire llvm system it's pretty good for something still in
diapers.

Now take XCode, that is some real drunk.

~~~
mrdrozdov
Swift development began in 2010.

------
melling
The work around was discussed on reddit, which is add the type information for
the dictionary:

[https://www.reddit.com/r/programming/comments/4givdg/go_home...](https://www.reddit.com/r/programming/comments/4givdg/go_home_swift_compiler_youre_drunk/?sort=confidence)

"edit: for the code, it's just changing let myCompany to

let myCompany: [String: [String: [String: String]]]'

------
stevejohnson
I recently wrote a tool to report Swift block compile times, since this kind
of thing can be unpredictable. At Hipmunk we run it every night to find out
how we can make our builds faster.

Another common culprit of slow compile times is usage of lazy var.

[https://github.com/irskep/swift_compile_times_parser](https://github.com/irskep/swift_compile_times_parser)

~~~
jopamer
Thanks, Steve! I'm well aware of the type checker's problems with 'lazy', and
it's something I hope to address soon.

~~~
stevejohnson
While you're here, I should say: first, thanks for your work, and second, it
would be nice if the compiler could log the timing data in a consolidated form
so my script wouldn't be necessary. :-) Regex-parsing and aggregating a bunch
of log lines seems dicey.

~~~
jopamer
Unfortunately, debug-time-function-bodies isn't an "officially" supported
flag, so improving it isn't a high priority right now.

...That said, we'd be more than happy to take improvement PRs in this area, if
you're feeling up for it!

------
msoad
I guess this means in large application you should always annotate your types.
It should be enforced with a linter.

~~~
geophile
I've been using Swift for a couple of months now. While I appreciate that type
inference makes for more concise and cleaner code, it also impedes code
comprehension. The absence of explicit types forces me, reading an unfamiliar
piece of code, to work harder to figure out the type of each expression. This
is especially true for expressions of type Optional<T>.

(But at least each expression _has_ a type. While I love Python and have used
it for many years, I don't like the uncertainty about types.)

~~~
mikeash
If you're using Xcode, you can option-click a variable and (if Xcode's
indexing is working, which is not a certainty) it'll show you the inferred
type for that variable. This can help when looking at some new code and trying
to figure out what all the bits really are.

~~~
geophile
Yeah, I know, but it's been unreliable.

------
yandrypozo
Wow, this is so sad, that compiler has to be extremely bad implemented

~~~
pshc
It's just a bug. It's pretty easy to accidentally have such cases in a generic
type inference algorithm, particularly one with implicit conversions. Other
similar languages have had pathological cases in type inference too.

~~~
mpweiher
>It's just a bug [..]

>Other similar languages have had pathological cases in type inference, too

These two statements are slightly contradictory. If this is common, then it's
not just a bug, but a difficulty in implementing type inference.

