val initialization semantic is counterintuitive

143 views
Skip to first unread message

Eugen Labun

unread,
Mar 22, 2011, 11:14:16 AM3/22/11
to scala-l...@googlegroups.com
Hi all,

eventually (or even surely) this is an old question but I haven't found an explanation for this
simple situation (nor in Language Specification, nor in Scala-Book).

(More complicated cases are described in this excellent faq from Paul:
https://github.com/paulp/scala-faq/wiki/Initialization-Order)


Constructions like

def m {
val x = y // compile error "forward reference extends over definition of value x"
val y = 5
}

cause a compile error if used in methods,
but are accepted in constructors/initializers:

class/object T {
val x = y // compiles OK, x = 0
val y = 5
}

The 'x' in the code above gets initialized to 0 (!), not to 5.


Both -- acceptance by the compiler and initialization to 0 -- are counterintuitive to me.
Would a compile error for the second case ("illegal forward reference") not be a more preferable?


I'm aware of '-Xcheckinit' compiler option. But this introduces only *runtime* check and doesn't
prevent the code to compile.


There was a ticket https://lampsvn.epfl.ch/trac/scala/ticket/399, but it's closed. I cannot
understand the reason of closing (it cites one more example of such counterintuitive behavior but
doesn't explain why this behavior can't be changed).


Java handles a semantically analogous situation as expected:

class C {
final int a = 3;
{
System.out.println("a: " + a); // OK
System.out.println("y: " + y); // Error: illegal forward reference
}
final int x = y; // Error: illegal forward reference
final int y = 5;

public static void main(String[] args) {
// final int x = y; // Error: cannot find symbol variable y
final int y = 5;
}
}


I understand that Scala vals do not map 1:1 to Java final variables, and that generating bytecode
from Scala code is much more complicated (having in mind such things as unified access principle and
therefore introducing methods for vals/vars, mapping of Scala's primary constructor to constructors
and initializers in Java, inheritance and overriding val->def->var, ...)

But, despite how complicated can be the generated code, hopefully, might it be possible to detect
such forward references in Scala parser and generate an error?


--
Regards,
Eugen

Sofoklis Papasofokli

unread,
Sep 9, 2016, 7:42:31 PM9/9/16
to scala-language
Hi,

Strange that nobody commented on this one for so long.

I know its an old thread but i keep getting issues from this, I also believe there should be a compiler error in this situation, its totally unexpected behavior.

Best Regards,
Sofoklis

martin odersky

unread,
Sep 10, 2016, 4:44:07 PM9/10/16
to scala-l...@googlegroups.com
I think that's a suggestion worth considering! In general it is extremely hard to detect uninitialized fields statically. But a scheme of disallowing direct forward references is easy to do and catches the most obvious bugs. 

Cheers

 - Martin



--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-language+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Martin Odersky
EPFL and Lightbend

Adriaan Moors

unread,
Sep 11, 2016, 4:37:57 AM9/11/16
to scala-l...@googlegroups.com
Val initialization is confusing, I agree, but note that you do get a warning. I'm a bit concerned about making this an error as you could override `val x` in a subclass (it's still weird, but should it be an error?).

Welcome to Scala 2.12.0-RC1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions for evaluation. Or try :help.

scala> class T {
     |   val x = y // compiles OK, x = 0
     |   val y = 5
     | }
<console>:12: warning: Reference to uninitialized value y
         val x = y // compiles OK, x = 0
                 ^

To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--

Martin Odersky
EPFL and Lightbend

--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.

Sébastien Doeraene

unread,
Sep 11, 2016, 4:54:01 AM9/11/16
to scala-l...@googlegroups.com
Hello,

Fun fact: we even have a test in Scala.js that makes sure that it behaves like that even for Scala.js-defined JS classes ^^
https://github.com/scala-js/scala-js/blob/v0.6.12/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala#L359-L367

Btw, indeed, this is one of the 5 warnings that we get when compiling our test suite (not counting deprecation warnings):

[warn] .../ScalaJSDefinedTest.scala:361: Reference to uninitialized value y
[warn]       val x = y
[warn]               ^


Cheers,
Sébastien

To unsubscribe from this group and stop receiving emails from it, send an email to scala-language+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--

Martin Odersky
EPFL and Lightbend

--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-language+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-language+unsubscribe@googlegroups.com.

martin odersky

unread,
Sep 11, 2016, 5:43:10 AM9/11/16
to scala-l...@googlegroups.com
On Sun, Sep 11, 2016 at 10:53 AM, Sébastien Doeraene <sjrdo...@gmail.com> wrote:
Hello,

Fun fact: we even have a test in Scala.js that makes sure that it behaves like that even for Scala.js-defined JS classes ^^
https://github.com/scala-js/scala-js/blob/v0.6.12/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefinedTest.scala#L359-L367

Btw, indeed, this is one of the 5 warnings that we get when compiling our test suite (not counting deprecation warnings):

[warn] .../ScalaJSDefinedTest.scala:361: Reference to uninitialized value y
[warn]       val x = y
[warn]               ^


Was that a real failure, or just a test to exercise this specifically? 

Cheers

 - Martin

Sébastien Doeraene

unread,
Sep 11, 2016, 6:03:20 AM9/11/16
to scala-l...@googlegroups.com
It's just a test to exercise this specifically. It was added at the exact same time we implemented Scala.js-defined JS classes, so there never was a (committed) bug.

For Scala.js-defined JS classes, the object initialization scheme is, implementation-wise, significantly different from the one used for Scala classes. Hence we have tests for known corner-cases of Scala initialization order, to make sure we're (bug-)compatible.

Cheers,
Sébastien

Sofoklis Papasofokli

unread,
Sep 11, 2016, 9:34:28 AM9/11/16
to scala-language
Hi Adriaan,

Indeed you get a warning, i have a slightly different case minimized bellow that has no warning or error:

object Ts {
   def gety = y
   val x = gety // compiles OK and no warning, x = 0

Viktor Klang

unread,
Sep 11, 2016, 9:44:39 AM9/11/16
to scala-l...@googlegroups.com
Hi Sofoklis,

On Sun, Sep 11, 2016 at 3:34 PM, Sofoklis Papasofokli <sofok...@gmail.com> wrote:
Hi Adriaan,

Indeed you get a warning, i have a slightly different case minimized bellow that has no warning or error:

object Ts {
   def gety = y
   val x = gety // compiles OK and no warning, x = 0
   val y = 5
 }

public class Ts {
  final int x;
  final int y;
  public Ts() {
    x = gety();  // compiles OK and no warning, x = 0
    y = 5;
  }
  private int gety() { return y; }
}

 
To unsubscribe from this group and stop receiving emails from it, send an email to scala-language+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Cheers,
Reply all
Reply to author
Forward
0 new messages