Re: Re: val initialization semantic is counterintuitive
martin odersky <[email protected]> Sat, 10 Sep 2016 22:43:42 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CAENVNkbz__h6S+bhRNq4VOx_=h2UDBH-V7PjTOkzw_zApOd4Ug@mail.gmail.com> |
--001a1130c178ba4b5b053c2d524e Content-Type: text/plain; charset=UTF-8 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 <[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 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 [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. --001a1130c178ba4b5b053c2d524e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">I think that's a suggestion worth considering! In gene= ral it is extremely hard to detect uninitialized fields statically. But a s= cheme of disallowing direct forward references is easy to do and catches th= e most obvious bugs.=C2=A0<div><br></div><div>Cheers</div><div><br></div><d= iv>=C2=A0- Martin<br><div><br></div><div><br></div></div></div><div class= =3D"gmail_extra"><br><div class=3D"gmail_quote">On Sat, Sep 10, 2016 at 1:4= 2 AM, Sofoklis Papasofokli <span dir=3D"ltr"><<a href=3D"mailto:sofoklis= [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,<br><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 there should be a compi= ler error in this situation, its totally unexpected behavior.<br><br>Best R= egards,<br>Sofoklis<br><br>On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, = Eugen Labun wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margi= n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<p>eventua= lly (or even surely) this is an old question but I haven't found an exp= lanation for this<br>simple situation (nor in Language Specification, nor i= n Scala-Book).</p><p>(More complicated cases are described in this excellen= t faq from Paul:<br><a href=3D"https://github.com/paulp/scala-faq/wiki/Init= ialization-Order" rel=3D"nofollow" target=3D"_blank">https://github.com/pau= lp/scala<wbr>-faq/wiki/Initialization-Order</a><wbr>)</p><p><br>Constructio= ns 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 error if used in metho= ds,<br>but are accepted in constructors/initializers:</p><p>=C2=A0 class/ob= ject 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 in= itialized to 0 (!), not to 5.</p><p><br>Both -- acceptance by the compiler = and initialization to 0 -- are counterintuitive to me.<br>Would a compile e= rror for the second case ("illegal forward reference") not be a m= ore preferable?</p><p><br>I'm aware of '-Xcheckinit' compiler o= ption. But 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://lampsv= n.epfl.ch/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 can= not<br>understand the reason of closing (it cites one more example of such = counterintuitive behavior but<br>doesn't explain why this behavior can&= #39;t be changed).</p><p><br>Java handles a semantically analogous situatio= n as expected:</p><p>=C2=A0 class C {<br>=C2=A0 =C2=A0 final int a =3D 3;<b= r>=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); // Error: illegal forward reference<br>=C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0= final int x =3D y; =C2=A0// Error: illegal forward reference<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 fin= d 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 vals do not map 1:1 = to Java final variables, and that generating bytecode<br>from Scala code is= much more complicated (having in mind such things as unified access princi= ple and<br>therefore introducing methods for vals/vars, mapping of Scala= 9;s primary constructor to constructors<br>and initializers in Java, inheri= tance and overriding val->def->var, ...)</p><p>But, despite how compl= icated can be the generated code, hopefully, might it be possible to detect= <br>such forward references in Scala parser and generate an error?</p><p><b= r><span class=3D"HOEnZb"><font color=3D"#888888">--<br>Regards,<br>Eugen<br= ></font></span></p><span class=3D"HOEnZb"><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 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><br><br clear=3D"all"><div><br></div>-- <b= r><div class=3D"gmail_signature" data-smartmail=3D"gmail_signature"><br>Mar= tin Odersky<br>EPFL and Lightbend</div> </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 /> --001a1130c178ba4b5b053c2d524e--