The Dark Secrets of Fast Compilation for Kotlin
blog.jetbrains.com
blog.jetbrains.com
Lucid Energize did it: https://www.youtube.com/watch?v=pQQTScuApWk
Incomplete source code: https://archive.org/details/archiveteam-lucid-collection
Furthermore, IntelliJ (as much as I love it) has a terrible live compilation story compared to eclipse. Eclipse recompiles affected project files while you type and propagates errors live. Harp on java where it's at least factual, (crufty stdlib, missing uints, type erasure..). Java is miles ahead what tooling and maturity of the ecosystem is concerned.
I'm not mainly a Java person, but I do sometimes pitch in here and there. We're using maven, and it's definitely not doing incremental compilation. I mentioned this was crazy to the Java guys and they said it was normal for maven...
(They're also in an IDE most of the time, so maybe they don't care so much.)
> Changes detected - recompiling the module!
> [INFO] Compiling 734 source files...
Perhaps we're doing something strange or dumb or somehow don't have incremental compilation turned on...
Setting the flag to false causes it to compile only changed files, but this will give incorrect results, for the reasons described in the Kotlin blog post.
I’m not knowledgeable enough to read between the lines, but is this a veiled reference to Go? If so, what about Go is intentionally not smart, and why? (Or language X)
The go language doesn't have either if those things, so the compiler has less work to do per line of code. But it seems like you knew that? You're the one that brought up Go.
See Rob Pike’s 2012 talk “Go at Google: Language Design in the Service of Software Engineering”
video + slides: https://www.infoq.com/presentations/Go-Google/
transcript: https://talks.golang.org/2012/splash.article#TOC_5.
Some of the things it calls out:
- unused dependencies are a compile-time error
- dependency graph has no cycles
- importing a package only looks at object files, not source files, so template/macro stuff is generally out
- declaration order is reverse from that of C so that parsing code is faster and easierI had a test suite that used `StringSpec` to make tests prettier to write, but after a few hundreds of those, my Kotlin tests started taking visibly longer to compile than the Java source code (which was much larger)! So I had to re-write the tests to use plain Kotlin functions instead.
All languages I know that have "advanced features" have notably slow compilers: Rust, Scala, Haskell. I would be happy to know if there's any counter-examples (I might almost include Kotlin as a counter-example, actually, as it's not so bad if you let it run the Gradle daemon to use the techniques mentioned in the article - but that feels a little bit like cheating as you're getting fast by just avoiding compiling everything).
So while I think the trade-off is worth it most of the time, it's something to be aware of and consider in your decision when choosing a language.
And in fact type inference is generally not what slows down compilation. It is often barely any more expensive than type checking (and indeed for languages with global type inference a viable way to implement type checking is to run type inference and then compare the generated type signature with the annotated signature). This is especially true for OCaml which requires definitions to be in order or otherwise explicitly marked as recursive (so the type inferencing algorithm can immediately add a term's inferred type to the current typing judgment as a known type). What's slow is usually recursive implicit definitions and optimizations. This means typeclass-heavy signatures for Haskell and frequent use of recursive implicits in Scala.
[1]: https://lemire.me/blog/2020/06/04/the-go-compiler-needs-to-b...