tags:

views:

101

answers:

2

I got the following code snippet referring an example in Chapter 6 of "Programming Scala":

object HelloWorld {
  def main(args: Array[String]) {
    trait AbstractT2 {
      println("In AbstractT2:")
      val value: Int
      val inverse = 1.0 / value // ???
      println("AbstractT2: value = " + value + ", inverse = " + inverse)
    }

    val c2b = new AbstractT2 {
      println("In c2b:")   //---->line 1
      val value = 10       //---->line 2
    }
    println("c2b.value = " + c2b.value + ", inverse = " + c2b.inverse)
  }
}

The result of the above code is:

In AbstractT2:
AbstractT2: value = 0, inverse = Infinity
In c2b:
c2b.value = 10, inverse = Infinity

Since the anonymous class initialization is after the trait initialization, the result is understandable. But if I exchange line 1 and line 2 in the above example, so that val value = 10 precedes println("In c2b:"), the result will be:

In AbstractT2:
AbstractT2: value = 10, inverse = 0.1
In c2b:
c2b.value = 10, inverse = 0.1

It seems this time the initialization is successful although it's wrong from language point of view. I can't understand why. Can anybody help on this? Thanks a lot.

+5  A: 

Initialization semantics changed from 2.7 to 2.8. Here's the commit, way back in 2008. "HARD HATS ON!"

https://lampsvn.epfl.ch/trac/scala/changeset/16745

extempore
Hi, do you mean the current behavior in 2.7 is also correct as designed? Thanks.
Hongfei
I mean that the behavior you are demonstrating is the expected behavior in 2.7. "Correct" is a more ambitious claim with I can neither confirm nor deny, but the point is moot unless you would like to start maintaining the 2.7 branch.
extempore
+3  A: 

Up to 2.7 Scala moved value initializations in front of the superclass constructor until an initialization which references this was encountered. There it would stop. Much, much earlier, this behavior was necessary to get some composition patterns working. Later, we introduced early definitions to get the same patterns working in a more robust way. But since the behavior was difficult to change it took us until 2.8 to actually do it.

Martin Odersky