Re: val initialization semantic is counterintuitive

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Sofoklis
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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:
<a href="https://github.com/paulp/scala-faq/wiki/Initialization-Order" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g&#39;;return true;">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 <a href="https://lampsvn.epfl.ch/trac/scala/ticket/399" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flampsvn.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flampsvn.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA&#39;;return true;">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

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

martin odersky-2
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Adriaan Moors-7
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[hidden email]> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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 [hidden email].
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Sébastien Doeraene
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

On Sun, Sep 11, 2016 at 10:37 AM, Adriaan Moors <[hidden email]> wrote:
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[hidden email]> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

martin odersky-2

On Sun, Sep 11, 2016 at 10:53 AM, Sébastien Doeraene <[hidden email]> 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


 
Cheers,
Sébastien

On Sun, Sep 11, 2016 at 10:37 AM, Adriaan Moors <[hidden email]> wrote:
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[hidden email]> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Sébastien Doeraene
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

On Sun, Sep 11, 2016 at 11:42 AM, martin odersky <[hidden email]> wrote:

On Sun, Sep 11, 2016 at 10:53 AM, Sébastien Doeraene <[hidden email]> 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


 
Cheers,
Sébastien

On Sun, Sep 11, 2016 at 10:37 AM, Adriaan Moors <[hidden email]> wrote:
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[hidden email]> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Sofoklis
In reply to this post by Adriaan Moors-7
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
 }


On Sunday, September 11, 2016 at 11:37:57 AM UTC+3, Adriaan Moors wrote:
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="W2H_ZtSgBgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">ode...@...> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="W2H_ZtSgBgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">sofok...@...> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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:
<a href="https://github.com/paulp/scala-faq/wiki/Initialization-Order" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g&#39;;return true;">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 <a href="https://lampsvn.epfl.ch/trac/scala/ticket/399" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flampsvn.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Flampsvn.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA&#39;;return true;">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

--
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 <a href="javascript:" target="_blank" gdf-obfuscated-mailto="W2H_ZtSgBgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">scala-languag...@googlegroups.com.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">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 <a href="javascript:" target="_blank" gdf-obfuscated-mailto="W2H_ZtSgBgAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">scala-languag...@googlegroups.com.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: val initialization semantic is counterintuitive

Viktor Klang
Hi Sofoklis,

On Sun, Sep 11, 2016 at 3:34 PM, Sofoklis Papasofokli <[hidden email]> 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; }
}

 


On Sunday, September 11, 2016 at 11:37:57 AM UTC+3, Adriaan Moors wrote:
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
                 ^

On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[hidden email]> wrote:
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



On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[hidden email]> wrote:
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

On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wrote:
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

--
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.
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.
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
Cheers,

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.