Re: Re: val initialization semantic is counterintuitive
Viktor Klang <[email protected]> Sun, 11 Sep 2016 15:44:16 +0200
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <CANPzfU81jFLVv=DXwx=rJcYT6eC3+9mOisYbkL2mJ-G0n3q3Pg@mail.gmail.com> |
--001a113ce0ba8fac66053c3b94a2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Sofoklis, On Sun, Sep 11, 2016 at 3:34 PM, Sofoklis Papasofokli <[email protected]= > 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 =3D y > val x =3D gety // compiles OK and no warning, x =3D 0 > val y =3D 5 > } > public class Ts { final int x; final int y; public Ts() { x =3D gety(); // compiles OK and no warning, x =3D 0 y =3D 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 =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 mos= t >>> 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 totall= y >>>> 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 =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, 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. >>> >> -- > 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 Cheers, =E2=88=9A --=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. --001a113ce0ba8fac66053c3b94a2 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Hi Sofoklis,<br><div class=3D"gmail_extra"><br><div class= =3D"gmail_quote">On Sun, Sep 11, 2016 at 3:34 PM, Sofoklis Papasofokli <spa= n dir=3D"ltr"><<a href=3D"mailto:[email protected]" target=3D"_blank"= >[email protected]</a>></span> wrote:<br><blockquote class=3D"gmail_q= uote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,2= 04);padding-left:1ex"><div dir=3D"ltr">Hi Adriaan,<br><br>Indeed you get a = warning, i have a slightly different case minimized bellow that has no warn= ing or error:<br><br>object Ts {<br>=C2=A0=C2=A0 def gety =3D y<br>=C2=A0= =C2=A0 val x =3D gety // compiles OK and no warning, x =3D 0<br>=C2=A0=C2= =A0 val y =3D 5<span class=3D"gmail-"><br>=C2=A0}<br></span></div></blockqu= ote><div><br></div><div><div>public class Ts {</div><div>=C2=A0 final int x= ;</div><div>=C2=A0 final int y;</div><div>=C2=A0 public Ts() {</div><div>= =C2=A0 =C2=A0 x =3D gety(); =C2=A0// compiles OK and no warning, x =3D 0</d= iv><div>=C2=A0 =C2=A0 y =3D 5;</div><div>=C2=A0 }</div><div>=C2=A0 private = int gety() { return y; }</div><div>}</div></div><div><br></div><div>=C2=A0<= /div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo= rder-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><sp= an class=3D"gmail-"><br><br>On Sunday, September 11, 2016 at 11:37:57 AM UT= C+3, Adriaan Moors wrote:</span><blockquote class=3D"gmail_quote" style=3D"= margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef= t:1ex"><span class=3D"gmail-"><div dir=3D"ltr"><div>Val initialization is c= onfusing, I agree, but note that you do get a warning. I'm a bit concer= ned about making this an error as you could override `val x` in a subclass = (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).</font></di= v><div><font face=3D"monospace">Type in expressions for evaluation. Or try = :help.</font></div><div><font face=3D"monospace"><br></font></div><div><fon= t face=3D"monospace">scala> class T {</font></div><div><font face=3D"mon= ospace">=C2=A0 =C2=A0 =C2=A0| =C2=A0 val x =3D y // compiles OK, x =3D 0</f= ont></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| }</fo= nt></div><div><font face=3D"monospace"><b><console>:12: warning: Refe= rence 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</fo= nt></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></span><div class=3D"gma= il_quote"><span class=3D"gmail-"><div dir=3D"ltr">On Sat, Sep 10, 2016 at 1= 0:44 PM martin odersky <<a rel=3D"nofollow">[email protected]</a>> wro= te:<br></div></span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0= px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span= class=3D"gmail-"><div dir=3D"ltr">I think that's a suggestion worth co= nsidering! In general it is extremely hard to detect uninitialized fields s= tatically. But a scheme of disallowing 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- Martin<br><div><br></div><div><br></div></div>= </div><div></div></span><div><br><div class=3D"gmail_quote"><div><div class= =3D"gmail-h5">On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <span d= ir=3D"ltr"><<a rel=3D"nofollow">[email protected]</a>></span> wrote:= <br></div></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0= px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div= class=3D"gmail-h5"><div dir=3D"ltr">Hi,<br><br>Strange that nobody comment= ed on this one for so long. <br><br>I know its an old thread but i keep get= ting issues from this, I also believe there should be a compiler error in t= his situation, its totally unexpected behavior.<br><br>Best Regards,<br>Sof= oklis<br><br>On Tuesday, March 22, 2011 at 5:14:16 PM UTC+2, Eugen Labun wr= ote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor= der-left:1px solid rgb(204,204,204);padding-left:1ex">Hi all,<p>eventually = (or even surely) this is an old question but I haven't found an explana= tion for this<br>simple situation (nor in Language Specification, nor in Sc= ala-Book).</p><p>(More complicated cases are described in this excellent fa= q from Paul:<br><a href=3D"https://github.com/paulp/scala-faq/wiki/Initiali= zation-Order" rel=3D"nofollow" target=3D"_blank">https://github.com/paulp/s= cala<wbr>-faq/wiki/Initialization-Order</a><wbr>)</p><p><br>Constructions l= ike</p><p>=C2=A0 def m {<br>=C2=A0 =C2=A0 val x =3D y // compile error &quo= t;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 methods,= <br>but are accepted in constructors/initializers:</p><p>=C2=A0 class/objec= t 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 initi= alized 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 erro= r for the second case ("illegal forward reference") not be a more= preferable?</p><p><br>I'm aware of '-Xcheckinit' compiler opti= on. 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://lampsvn.e= pfl.ch/trac/scala/ticket/399" rel=3D"nofollow" target=3D"_blank">https://la= mpsvn.epfl.ch/trac/s<wbr>cala/ticket/399</a>, but it's closed. I cannot= <br>understand the reason of closing (it cites one more example of such cou= nterintuitive behavior but<br>doesn't explain why this behavior can'= ;t be changed).</p><p><br>Java handles a semantically analogous situation a= s expected:</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)= ; // Error: illegal forward reference<br>=C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0 f= inal 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><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></div></div><span><font color=3D"#888888"><div><div cla= ss=3D"gmail-h5"> <p></p> -- <br> You received this message because you are subscribed to the Google Groups &= quot;scala-language" group.<br></div></div> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a rel=3D"nofollow">scala-languag...@googlegroups.<wbr>com</a>.<spa= n class=3D"gmail-"><br> For more options, visit <a href=3D"https://groups.google.com/d/optout" rel= =3D"nofollow" target=3D"_blank">https://groups.google.com/d/op<wbr>tout</a>= .<br> </span></font></span></blockquote></div><br><br clear=3D"all"><div><br></di= v></div><span class=3D"gmail-"><div>-- <br><div><br>Martin 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></span> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a rel=3D"nofollow">scala-languag...@googlegroups.<wbr>com</a>.<spa= n class=3D"gmail-"><br> For more options, visit <a href=3D"https://groups.google.com/d/optout" rel= =3D"nofollow" target=3D"_blank">https://groups.google.com/d/op<wbr>tout</a>= .<br> </span></blockquote></div> </blockquote></div><div class=3D"gmail-HOEnZb"><div class=3D"gmail-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><br clear=3D"all"><div><br></div>-- <br>= <div class=3D"gmail_signature"><div dir=3D"ltr"><div><span style=3D"border-= collapse:separate;color:rgb(0,0,0);font-family:times;font-variant-ligatures= :normal;font-variant-caps:normal;letter-spacing:normal;line-height:normal;t= ext-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:norm= al;word-spacing:0px;font-size:medium"><div style=3D"color:rgb(34,34,34);fon= t-family:arial,sans-serif;font-size:13.3333px">Cheers,</div><div style=3D"c= olor:rgb(34,34,34);font-family:arial,sans-serif;font-size:13.3333px">=E2=88= =9A</div></span></div></div></div> </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 /> --001a113ce0ba8fac66053c3b94a2--