5

Why in this example, no error is thrown and b ends up holding default value?

scala> val b = a; val a = 5
b: Int = 0
a: Int = 5

1 Answer 1

11

When you do this in the REPL, you are effectively doing:

class Foobar { val b = a; val a = 5 }

b and a are assigned to in order, so at the time when you're assigning b, there is a field a, but it hasn't yet been assigned to, so it has the default value of 0. In Java, you can't do this because you can't reference a field before it is defined. I believe you can do this in Scala to allow lazy initialisation.

You can see this more clearly if you use the following code:

scala> class Foobar {
  println("a=" + a)
  val b = a
  println("a=" + a)
  val a = 5
  println("a=" + a)
}
defined class Foobar

scala> new Foobar().b
a=0
a=0
a=5
res6: Int = 0

You can have the correct values assigned if you make a a method:

class Foobar { val b = a; def a = 5 }
defined class Foobar
scala> new Foobar().b
res2: Int = 5

or you can make b a lazy val:

scala> class Foobar { lazy val b = a; val a = 5 }
defined class Foobar

scala> new Foobar().b
res5: Int = 5
Sign up to request clarification or add additional context in comments.

3 Comments

Shouldn't scalac issue a warning in such situations? Since it seems to be a sure bug and will probably lead to funny bugs sometimes.
@Rogach it could be a warning in the Scala compiler I suppose, but it may well be useful, esp. for lazy evaluation. More in the realms of a style checker such as scalastyle (github.com/scalastyle/scalastyle)
@Rogach Detecting such situations reliably is hard, if not impossible. Scalac will probably have warning for simple cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.