Re: Re: val initialization semantic is counterintuitive
Sébastien Doeraene <[email protected]> Sun, 11 Sep 2016 12:02:48 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAJwkOg7NaY8n7JGzW5J2XXxfOtEBxwNk0K6QY4h7kZoa_5gY2g@mail.gmail.com> |
--001a113ce13489138e053c387cd8 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 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=C3=A9bastien On Sun, Sep 11, 2016 at 11:42 AM, martin odersky <[email protected]> wrote: > > On Sun, Sep 11, 2016 at 10:53 AM, S=C3=A9bastien Doeraene < > [email protected]> wrote: > >> Hello, >> >> Fun fact: we even have a test in Scala.js that makes sure that it behave= s >> 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/ScalaJSDe >> finedTest.scala#L359-L367 >> >> Btw, indeed, this is one of the 5 warnings that we get when compiling ou= r >> test suite (not counting deprecation warnings): >> >> [warn] .../ScalaJSDefinedTest.scala:361: Reference to uninitialized >> value y >> [warn] val x =3D y >> [warn] ^ >> >> Was that a real failure, or just a test to exercise this specifically? > > Cheers > > - Martin > > > > >> 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 >>>> extremely hard to detect uninitialized fields statically. But a scheme= of >>>> disallowing direct forward references is easy to do and catches the mo= st >>>> obvious bugs. >>>> >>>> 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 total= ly >>>>> 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 Pau= l: >>>>>> 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 >>>>>> reference >>>>>> } >>>>>> 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 >>>>>> 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, sen= d >>>>> 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 >>>> 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. >>>> >>> -- >>> 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. >>> >> >> -- >> 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. >> > > > > -- > > 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 [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. --001a113ce13489138e053c387cd8 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div><div>It's just a test to exercise this specifical= ly. It was added at the exact same time we implemented Scala.js-defined JS = classes, so there never was a (committed) bug.<br><br></div>For Scala.js-de= fined 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 w= e're (bug-)compatible.<br><br></div><div>Cheers,<br></div>S=C3=A9bastie= n<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Sun= , Sep 11, 2016 at 11:42 AM, martin odersky <span dir=3D"ltr"><<a href=3D= "mailto:[email protected]" target=3D"_blank">[email protected]</a>></spa= n> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b= order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"= gmail_extra"><br><div class=3D"gmail_quote"><span class=3D"">On Sun, Sep 11= , 2016 at 10:53 AM, S=C3=A9bastien Doeraene <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"><di= v><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/scala-js/blob/v0.6.12/= test-suite/js/src/test/scala/org/scalajs/testsuite/jsinterop/ScalaJSDefined= Test.scala#L359-L367" target=3D"_blank">https://github.com/scala-js/sc<wbr>= ala-js/blob/v0.6.12/test-suite<wbr>/js/src/test/scala/org/scalajs<wbr>/test= suite/jsinterop/ScalaJSDe<wbr>finedTest.scala#L359-L367</a><br></div><br>Bt= w, indeed, this is one of the 5 warnings that we get when compiling our tes= t suite (not counting deprecation warnings):<br><br><span style=3D"font-fam= ily:monospace,monospace">[warn] .../ScalaJSDefinedTest.scala:3<wbr>61: Refe= rence 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></div></div></bl= ockquote></span><div>Was that a real failure, or just a test to exercise th= is specifically?=C2=A0</div><div><br></div><div>Cheers</div><span class=3D"= HOEnZb"><font color=3D"#888888"><div><br></div><div>=C2=A0- Martin</div></f= ont></span><div><div class=3D"h5"><div><br></div><div><br></div><div>=C2=A0= </div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l= eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div></div>Cheer= s,<br></div>S=C3=A9bastien<br></div><div><div><div class=3D"gmail_extra"><b= r><div class=3D"gmail_quote">On Sun, Sep 11, 2016 at 10:37 AM, Adriaan Moor= s <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"><div>Val initialization is confusing, I agree, = but note that you do get a warning. I'm a bit concerned about making th= is an error as you could override `val x` in a subclass (it's still wei= rd, but should it be an error?).</div><div><font face=3D"monospace"><br></f= ont></div><div><font face=3D"monospace">Welcome to Scala 2.12.0-RC1 (Java H= otSpot(TM) 64-Bit Server VM, Java 1.8.0_102).</font></div><div><font face= =3D"monospace">Type in expressions for evaluation. Or try :help.</font></di= v><div><font face=3D"monospace"><br></font></div><div><font face=3D"monospa= ce">scala> class T {</font></div><div><font face=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></d= iv><div><font face=3D"monospace">=C2=A0 =C2=A0 =C2=A0| }</font></div><div><= font face=3D"monospace"><b><console>:12: warning: Reference to uninit= ialized 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 odersky <<a href=3D"mailto= :[email protected]" target=3D"_blank">[email protected]</a>> wrote:<br><= /div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le= ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I think that's a s= uggestion worth considering! In general it is extremely hard to detect unin= itialized fields statically. But a scheme of disallowing direct forward ref= erences is easy to do and catches the most obvious bugs.=C2=A0<div><br></di= v><div>Cheers</div><div><br></div><div>=C2=A0- Martin<br><div><br></div><di= v><br></div></div></div><div class=3D"gmail_extra"></div><div class=3D"gmai= l_extra"><br><div class=3D"gmail_quote">On Sat, Sep 10, 2016 at 1:42 AM, So= foklis Papasofokli <span dir=3D"ltr"><<a href=3D"mailto:sofoklis24@gmail= .com" target=3D"_blank">[email protected]</a>></span> wrote:<br><bloc= kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc= c solid;padding-left:1ex"><div dir=3D"ltr">Hi,<br><br>Strange that nobody c= ommented on this one for so long. <br><br>I know its an old thread but i ke= ep getting issues from this, I also believe there should be a compiler erro= r in this situation, its totally unexpected behavior.<br><br>Best Regards,<= br>Sofoklis<br><br>On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen La= bun wrote:<blockquote class=3D"gmail_quote" style=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 Specification, nor in Scala-= Book).</p><p>(More complicated cases are described in this excellent faq fr= om Paul:<br><a href=3D"https://github.com/paulp/scala-faq/wiki/Initializati= on-Order" rel=3D"nofollow" target=3D"_blank">https://github.com/paulp/scala= <wbr>-faq/wiki/Initialization-Order</a><wbr>)</p><p><br>Constructions like<= /p><p>=C2=A0 def m {<br>=C2=A0 =C2=A0 val x =3D y // compile error "fo= rward reference extends over definition of value x"<br>=C2=A0 =C2=A0 v= al y =3D 5<br>=C2=A0 }</p><p>cause a compile error if used in methods,<br>b= ut 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 initialize= d to 0 (!), not to 5.</p><p><br>Both -- acceptance by the compiler and init= ialization to 0 -- are counterintuitive to me.<br>Would a compile error for= the second case ("illegal forward reference") not be a more pref= erable?</p><p><br>I'm aware of '-Xcheckinit' compiler option. B= ut this introduces only *runtime* check and doesn't<br>prevent the code= to compile.</p><p><br>There was a ticket <a href=3D"https://lampsvn.epfl.c= h/trac/scala/ticket/399" rel=3D"nofollow" target=3D"_blank">https://lampsvn= .epfl.ch/trac/s<wbr>cala/ticket/399</a>, but it's closed. I cannot<br>u= nderstand the reason of closing (it cites one more example of such counteri= ntuitive behavior but<br>doesn't explain why this behavior can't be= changed).</p><p><br>Java handles a semantically analogous situation as exp= ected:</p><p>=C2=A0 class C {<br>=C2=A0 =C2=A0 final int a =3D 3;<br>=C2=A0= =C2=A0 {<br>=C2=A0 =C2=A0 =C2=A0 System.out.println("a: " + a); = // OK<br>=C2=A0 =C2=A0 =C2=A0 System.out.println("y: " + y); // E= rror: illegal forward reference<br>=C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0 final i= nt x =3D y; =C2=A0// Error: illegal forward reference<br>=C2=A0 =C2=A0 fina= l 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 }<b= r>=C2=A0 }</p><p><br>I understand that Scala vals do not map 1:1 to Java fi= nal variables, and that generating bytecode<br>from Scala code is much more= complicated (having in mind such things as unified access principle and<br= >therefore introducing methods for vals/vars, mapping of Scala's primar= y constructor to constructors<br>and initializers in Java, inheritance and = overriding val->def->var, ...)</p><p>But, despite how complicated can= be the generated code, hopefully, might it be possible to detect<br>such f= orward references in Scala parser and generate an error?</p><p><br><span><f= ont color=3D"#888888">--<br>Regards,<br>Eugen<br></font></span></p><span><f= ont 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></blockqu= ote></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@goo<wbr>glegroups.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/op<wbr>tout</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><font color=3D"#888888"= > </font></span></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@goo<wbr>glegroups.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/op<wbr>tout</a>.<br> </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@goo<wbr>glegroups.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/op<wbr>tout</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]" targ= et=3D"_blank">scala-language+unsubscribe@goo<wbr>glegroups.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/op<wbr>tout</a>.<br> </div></div></blockquote></div></div></div><div><div class=3D"h5"><br><br c= lear=3D"all"><div><br></div>-- <br><div data-smartmail=3D"gmail_signature">= <br>Martin Odersky<br>EPFL and Lightbend</div> </div></div></div></div><div class=3D"HOEnZb"><div class=3D"h5"> <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> </div></div></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 /> --001a113ce13489138e053c387cd8--