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">&lt;<a href=3D"mailto:[email protected]" target=3D"_blank"=
>[email protected]</a>&gt;</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&#39;m a bit concer=
ned about making this an error as you could override `val x` in a subclass =
(it&#39;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&gt; 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>&lt;console&gt;: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 &lt;<a rel=3D"nofollow">[email protected]</a>&gt; 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&#39;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">&lt;<a rel=3D"nofollow">[email protected]</a>&gt;</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&#39;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&quot;<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 &#39;x&#39; 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 (&quot;illegal forward reference&quot;) not be a more=
 preferable?</p><p><br>I&#39;m aware of &#39;-Xcheckinit&#39; compiler opti=
on. But this introduces only *runtime* check and doesn&#39;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&#39;s closed. I cannot=
<br>understand the reason of closing (it cites one more example of such cou=
nterintuitive behavior but<br>doesn&#39;t explain why this behavior can&#39=
;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(&quot;a: &quot; =
+ a); // OK<br>=C2=A0 =C2=A0 =C2=A0 System.out.println(&quot;y: &quot; + 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&#3=
9;s primary constructor to constructors<br>and initializers in Java, inheri=
tance and overriding val-&gt;def-&gt;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&quot; 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&quot; 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&quot; 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&quot; 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--