Yes, I know trait parameters are on their way which can mitigate the situation, but I find Scala’s initialization order very counter-intuitive. Consider the following example:
trait Foo {
val a : Int
println(a)
}
class Bar extends Foo {
val a : Int = 1
}
class LazyBar extends Foo {
lazy val a : Int = 1
}
new Bar //prints `0`
new LazyBar //prints `1`
As I look at it, using lazy val to change the initialization order isn’t what lazy is for, and looks more like a hack. For me, lazy is simply a function that runs only once.
Take the example above, Foo only works correctly if its successor defines a as lazy. This doesn’t make sense to me. In this case, I cannot even create a Foo without declaring a value for a. But even if a had an explicit initial value, I expect that the latest successor wins the initialization battle.