Re: Re: val initialization semantic is counterintuitive
Sébastien Doeraene <[email protected]> Sun, 11 Sep 2016 10:53:33 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAJwkOg4khdJkAn9C9Qgcw1W1_JroLM1q413wJN3k7aVVLw66QQ@mail.gmail.com> |
--001a113cfb2ce177c5053c37848e Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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/sc= ala/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 =3D y [warn] ^ Cheers, S=C3=A9bastien On Sun, Sep 11, 2016 at 10:37 AM, Adriaan Moors <[email protected]> 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 =3D y // compiles OK, x =3D 0 > | val y =3D 5 > | } > *<console>:12: warning: Reference to uninitialized value y* > val x =3D y // compiles OK, x =3D 0 > ^ > > On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[email protected]> wrote= : > >> I think that's a suggestion worth considering! In general it is extremel= y >> hard to detect uninitialized fields statically. But a scheme of disallow= ing >> direct forward references is easy to do and catches the most obvious bug= s. >> >> Cheers >> >> - Martin >> >> >> >> On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli < >> [email protected]> 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 foun= d >>>> 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 =3D y // compile error "forward reference extends over >>>> definition of value x" >>>> val y =3D 5 >>>> } >>>> >>>> cause a compile error if used in methods, >>>> but are accepted in constructors/initializers: >>>> >>>> class/object T { >>>> val x =3D y // compiles OK, x =3D 0 >>>> val y =3D 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 =3D 3; >>>> { >>>> System.out.println("a: " + a); // OK >>>> System.out.println("y: " + y); // Error: illegal forward referen= ce >>>> } >>>> final int x =3D y; // Error: illegal forward reference >>>> final int y =3D 5; >>>> >>>> public static void main(String[] args) { >>>> // final int x =3D y; // Error: cannot find symbol variable y >>>> final int y =3D 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 a= s >>>> unified access principle and >>>> therefore introducing methods for vals/vars, mapping of Scala's primar= y >>>> 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 [email protected]. >>> 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 Group= s >> "scala-language" group. >> To unsubscribe from this group and stop receiving emails from it, send a= n >> email to [email protected]. >> 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 [email protected]. > For more options, visit https://groups.google.com/d/optout. > --=20 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 e= mail to [email protected]. For more options, visit https://groups.google.com/d/optout. --001a113cfb2ce177c5053c37848e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div><div><div><div>Hello,<br><br></div>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 ^^<br><a href=3D"https://github.com/scala-js/sc= ala-js/blob/v0.6.12/test-suite/js/src/test/scala/org/scalajs/testsuite/jsin= terop/ScalaJSDefinedTest.scala#L359-L367">https://github.com/scala-js/scala= -js/blob/v0.6.12/test-suite/js/src/test/scala/org/scalajs/testsuite/jsinter= op/ScalaJSDefinedTest.scala#L359-L367</a><br></div><br>Btw, indeed, this is= one of the 5 warnings that we get when compiling our test suite (not count= ing deprecation warnings):<br><br><span style=3D"font-family:monospace,mono= space">[warn] .../ScalaJSDefinedTest.scala:361: Reference to uninitialized = value y<br>[warn]=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 val x =3D y<br>[warn]= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 ^</span><br><br></div>Cheers,<br></div>S=C3=A9bastien<br></div><d= iv class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Sun, Sep 11, 201= 6 at 10:37 AM, Adriaan Moors <span dir=3D"ltr"><<a href=3D"mailto:adriaa= [email protected]" target=3D"_blank">[email protected]</a>></span> wro= te:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-= left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Val initializat= ion is confusing, I agree, but note that you do get a warning. I'm a bi= t concerned about making this an error as you could override `val x` in a s= ubclass (it's still weird, but should it be an error?).</div><div><font= face=3D"monospace"><br></font></div><div><font face=3D"monospace">Welcome = to Scala 2.12.0-RC1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).</f= ont></div><div><font face=3D"monospace">Type in expressions for evaluation.= Or try :help.</font></div><div><font face=3D"monospace"><br></font></div><= div><font face=3D"monospace">scala> class T {</font></div><div><font fac= e=3D"monospace">=C2=A0 =C2=A0 =C2=A0| =C2=A0 val x =3D y // compiles OK, x = =3D 0</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0| =C2= =A0 val y =3D 5</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2= =A0| }</font></div><div><font face=3D"monospace"><b><console>:12: war= ning: Reference to uninitialized value y</b></font></div><div><font face=3D= "monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0val x =3D y // compiles OK, x= =3D 0</font></div><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^</font></div></div><br><div class=3D= "gmail_quote"><div dir=3D"ltr">On Sat, Sep 10, 2016 at 10:44 PM martin oder= sky <<a href=3D"mailto:[email protected]" target=3D"_blank">odersky@gmai= l.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"ma= rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt= r">I think that's a suggestion worth considering! In general it is extr= emely hard to detect uninitialized fields statically. But a scheme of disal= lowing direct forward references is easy to do and catches the most obvious= bugs.=C2=A0<div><br></div><div>Cheers</div><div><br></div><div>=C2=A0- Mar= tin<br><div><br></div><div><br></div></div></div><div class=3D"gmail_extra"= ></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Sat, Se= p 10, 2016 at 1:42 AM, Sofoklis Papasofokli <span dir=3D"ltr"><<a href= =3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>= ></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0= 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi,<b= r><br>Strange that nobody commented on this one for so long. <br><br>I know= its an old thread but i keep getting issues from this, I also believe ther= e should be a compiler error in this situation, its totally unexpected beha= vior.<br><br>Best Regards,<br>Sofoklis<br><br>On Tuesday, March 22, 2011 at= 5:14:16 PM UTC+2, Eugen Labun wrote:<blockquote class=3D"gmail_quote" styl= e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex= ">Hi all,<p>eventually (or even surely) this is an old question but I haven= 't found an explanation for this<br>simple situation (nor in Language S= pecification, nor in Scala-Book).</p><p>(More complicated cases are describ= ed in this excellent faq from Paul:<br><a href=3D"https://github.com/paulp/= scala-faq/wiki/Initialization-Order" rel=3D"nofollow" target=3D"_blank">htt= ps://github.com/paulp/<wbr>scala-faq/wiki/Initialization-<wbr>Order</a>)</p= ><p><br>Constructions like</p><p>=C2=A0 def m {<br>=C2=A0 =C2=A0 val x =3D = y // compile error "forward reference extends over definition of value= x"<br>=C2=A0 =C2=A0 val y =3D 5<br>=C2=A0 }</p><p>cause a compile err= or if used in methods,<br>but are accepted in constructors/initializers:</p= ><p>=C2=A0 class/object T {<br>=C2=A0 =C2=A0 val x =3D y // compiles OK, x = =3D 0<br>=C2=A0 =C2=A0 val y =3D 5<br>=C2=A0 }</p><p>The 'x' in the= code above gets initialized to 0 (!), not to 5.</p><p><br>Both -- acceptan= ce by the compiler and initialization to 0 -- are counterintuitive to me.<b= r>Would a compile error for the second case ("illegal forward referenc= e") not be a more preferable?</p><p><br>I'm aware of '-Xchecki= nit' compiler option. But this introduces only *runtime* check and does= n't<br>prevent the code to compile.</p><p><br>There was a ticket <a hre= f=3D"https://lampsvn.epfl.ch/trac/scala/ticket/399" rel=3D"nofollow" target= =3D"_blank">https://lampsvn.epfl.ch/trac/<wbr>scala/ticket/399</a>, but it&= #39;s closed. I cannot<br>understand the reason of closing (it cites one mo= re example of such counterintuitive behavior but<br>doesn't explain why= this behavior can't be changed).</p><p><br>Java handles a semantically= analogous situation as expected:</p><p>=C2=A0 class C {<br>=C2=A0 =C2=A0 f= inal int a =3D 3;<br>=C2=A0 =C2=A0 {<br>=C2=A0 =C2=A0 =C2=A0 System.out.pri= ntln("a: " + a); // OK<br>=C2=A0 =C2=A0 =C2=A0 System.out.println= ("y: " + y); // Error: illegal forward reference<br>=C2=A0 =C2=A0= }<br>=C2=A0 =C2=A0 final int x =3D y; =C2=A0// Error: illegal forward refe= rence<br>=C2=A0 =C2=A0 final int y =3D 5;</p><p>=C2=A0 =C2=A0 public static= void main(String[] args) {<br>=C2=A0 =C2=A0 =C2=A0 // final int x =3D y; /= / Error: cannot find symbol variable y<br>=C2=A0 =C2=A0 =C2=A0 final int y = =3D 5;<br>=C2=A0 =C2=A0 }<br>=C2=A0 }</p><p><br>I understand that Scala val= s do not map 1:1 to Java final variables, and that generating bytecode<br>f= rom Scala code is much more complicated (having in mind such things as unif= ied access principle and<br>therefore introducing methods for vals/vars, ma= pping of Scala's primary constructor to constructors<br>and initializer= s in Java, inheritance and overriding val->def->var, ...)</p><p>But, = despite how complicated can be the generated code, hopefully, might it be p= ossible to detect<br>such forward references in Scala parser and generate a= n error?</p><p><br><span><font color=3D"#888888">--<br>Regards,<br>Eugen<br= ></font></span></p><span><font color=3D"#888888"><p></p><p></p><p></p><p></= p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p>= </p></font></span></blockquote></div><span><font color=3D"#888888"> <p></p> -- <br> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" targ= et=3D"_blank">scala-language+unsubscribe@<wbr>googlegroups.com</a>.<br> For more options, visit <a href=3D"https://groups.google.com/d/optout" targ= et=3D"_blank">https://groups.google.com/d/<wbr>optout</a>.<br> </font></span></blockquote></div><br><br clear=3D"all"><div><br></div></div= ><div class=3D"gmail_extra">-- <br><div data-smartmail=3D"gmail_signature">= <br>Martin Odersky<br>EPFL and Lightbend</div><span class=3D"HOEnZb"><font = color=3D"#888888"> </font></span></div><span class=3D"HOEnZb"><font color=3D"#888888"> <p></p> -- <br> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" targ= et=3D"_blank">scala-language+unsubscribe@<wbr>googlegroups.com</a>.<br> For more options, visit <a href=3D"https://groups.google.com/d/optout" targ= et=3D"_blank">https://groups.google.com/d/<wbr>optout</a>.<br> </font></span></blockquote></div><span class=3D"HOEnZb"><font color=3D"#888= 888"> <p></p> -- <br> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]" targ= et=3D"_blank">scala-language+unsubscribe@<wbr>googlegroups.com</a>.<br> For more options, visit <a href=3D"https://groups.google.com/d/optout" targ= et=3D"_blank">https://groups.google.com/d/<wbr>optout</a>.<br> </font></span></blockquote></div><br></div> <p></p> -- <br /> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br /> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]">scal= [email protected]</a>.<br /> For more options, visit <a href=3D"https://groups.google.com/d/optout">http= s://groups.google.com/d/optout</a>.<br /> --001a113cfb2ce177c5053c37848e--