I consider it fair to expect the compiler to be slower when it's doing more heavy lifting, but it would definitely be nice to see the exponential blow-up on the tail curbed in future.
edit: To clarify, the numbers above were what Odersky claimed; I haven't verified them. The 1 line/minute was claimed of trying to build Shapeless - I've never seen anything approaching that in the wild.
I get that that's an upper limit, but that's still pretty shocking. Is there an overarching reason for this type of performance? Examples of this style of code?
https://michid.wordpress.com/2010/01/29/scala-type-level-enc...
I can't comment on the details, I'm more of of Clojure guy.
[1] https://github.com/scalaz/scalaz/blob/series/7.2.x/core/src/...
The main reason why Scala is slow is because the compiler is poorly written. Take a look at the articles from Paul Phillips, one of the Typesafe cofounders who left the company in frustration, he's probably the person who knows scalac the best and he says the code base is basically hopeless.
Note that 1/3rd of Martin's presentation is about Dotty, and that's basically where he spends most of his time these days, he hardly contributes to Scala any more [1].
It took only one sentence to show that you never used OCaml or Haskell, so I'm not sure how serious the rest of your claims should be taken.
Yes, but OCaml doesn't "offer very similar functionalities".
Haskell is quite a bit slower if you consider that you often have to compile not only your own code, but also the sources of your dependencies in the beginning. Additionally, you have to fight with Cabal, which tends to be very unpleasant due to the lack of any reasonable support for exotic things like "versions". Then you might discover hacks like "sandboxing". Hours not spent coding.
def f(x: Int) = if (x % 2 == 0) { x } else { None }
(This compiles, but the type of `f` is not `f: Int => Option[Int]`.)[edit: the bug is not in the scala compiler, the bug is in my code - I almost certainly did not want `f` to have type `Int => Any`. My phrasing, now edited, was misleading. ]
scala> def f(x: Int): Option[Int] = if (x % 2 == 0) { x } else { None } <console>:7: error: type mismatch; found : Int required: Option[Int] def f(x: Int): Option[Int] = if (x % 2 == 0) { x } else { None }
scala> def f(x: Int) = if (x % 2 == 0) { x } else { None }
f: (x: Int)Any
Which is expected. The only shared type between both branches of the `if` expression is `Any`.A language that supports union types (e.g. Ceylon) will type this expression as Int|Option[Int], which is as specific as you can get.
Option[Int] is simply an alias to the type Int | Null, so Int | Option[Int] would become Int | Int | Null after replacement, which simplifies to Int | Null since Int | Int is equivalent to just Int.
The gist is that once you have [edit: recursive] typeclasses or implicits your search can become arbitrarily large and slow. There's nothing that can be done about it by the compiler except arbitrarily pruning the search tree. Or otherwise put, you should factor in implicit search complexity when designing your libraries.
edit: reworded for clarity
Theoretically, there is nothing stopping you from writing code which will never finish compiling if you have a Turing-complete typesystem.
let f0 = fun x -> ( x, x ) in let f1 = fun y -> f0( f0 y ) in let f2 = fun y -> f1( f1 y ) in let f3 = fun y -> f2( f2 y ) in let f4 = fun y -> f3( f3 y ) in let f5 = fun y -> f4( f4 y ) in f5 ( fun z -> z );;
took at least 3 months (!) to type-infer when I ran it on my 2008 MacBook using the standard Ocaml compiler. I have not tried since. Type inference algorithms have horrendous worst-case complexity. Fortunately that worst-case complexity usually doesn't matter in practise.
Anyway, details aside I thought it was a great illustration of the impact on compiler performance that code complexity can have.
I get the impression that compiler preformance is being worked on, and is improving over time.