Re: Re: val initialization semantic is counterintuitive
Sofoklis Papasofokli <[email protected]> Sun, 11 Sep 2016 06:34:27 -0700 (PDT)
| Newsgroups | gmane.comp.lang.scala |
|---|---|
| Message-ID | <[email protected]> |
------=_Part_4721_1361046285.1473600867820
Content-Type: multipart/alternative;
boundary="----=_Part_4722_1883263192.1473600867820"
------=_Part_4722_1883263192.1473600867820
Content-Type: text/plain; charset=UTF-8
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 = y
val x = gety // compiles OK and no warning, x = 0
val y = 5
}
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 = y // compiles OK, x = 0
> | val y = 5
> | }
> *<console>:12: warning: Reference to uninitialized value y*
> val x = y // compiles OK, x = 0
> ^
>
> On Sat, Sep 10, 2016 at 10:44 PM martin odersky <[email protected]
> <javascript:>> 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 most obvious bugs.
>>
>> Cheers
>>
>> - Martin
>>
>>
>>
>> On Sat, Sep 10, 2016 at 1:42 AM, Sofoklis Papasofokli <[email protected]
>> <javascript:>> 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] <javascript:>.
>>> 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] <javascript:>.
>> 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.
------=_Part_4722_1883263192.1473600867820
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Adriaan,<br><br>Indeed you get a warning, i have a slig=
htly different case minimized bellow that has no warning or error:<br><br>o=
bject 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<br>=C2=A0}=
<br><br><br>On Sunday, September 11, 2016 at 11:37:57 AM UTC+3, Adriaan Moo=
rs wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
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 warni=
ng. I'm a bit concerned about making this an error as you could overrid=
e `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"mon=
ospace">Welcome to Scala 2.12.0-RC1 (Java HotSpot(TM) 64-Bit Server VM, Jav=
a 1.8.0_102).</font></div><div><font face=3D"monospace">Type in expressions=
for evaluation. Or try :help.</font></div><div><font face=3D"monospace"><b=
r></font></div><div><font face=3D"monospace">scala> class T {</font></di=
v><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></div><div><font face=3D"monospace">=
=C2=A0 =C2=A0 =C2=A0| }</font></div><div><font face=3D"monospace"><b><co=
nsole>:12: warning: 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 odersky <<a href=3D"javascript:" target=3D"_blank" gdf-obfu=
scated-mailto=3D"W2H_ZtSgBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D=
'javascript:';return true;" onclick=3D"this.href=3D'javascript:=
';return true;">[email protected]</a>> wrote:<br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr">I think that's a suggestion worth con=
sidering! In general it is extremely hard to detect uninitialized fields st=
atically. 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><div><br><div class=3D"gmail_quote">On Sat, Sep 10, 2016 at=
1:42 AM, Sofoklis Papasofokli <span dir=3D"ltr"><<a href=3D"javascript:=
" target=3D"_blank" gdf-obfuscated-mailto=3D"W2H_ZtSgBgAJ" rel=3D"nofollow"=
onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"=
this.href=3D'javascript:';return true;">[email protected]</a>><=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;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 sho=
uld be a compiler error 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 Labun 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 Specif=
ication, nor in Scala-Book).</p><p>(More complicated cases are described 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" onmoused=
own=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithu=
b.com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\=
x3d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g';return true;" onclic=
k=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.=
com%2Fpaulp%2Fscala-faq%2Fwiki%2FInitialization-Order\x26sa\x3dD\x26sntz\x3=
d1\x26usg\x3dAFQjCNFbDzgtf0NkRirePwBhH-zUPHp_5g';return true;">https://=
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&qu=
ot;<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/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 cod=
e above gets initialized to 0 (!), not to 5.</p><p><br>Both -- acceptance b=
y the compiler and initialization to 0 -- are counterintuitive to me.<br>Wo=
uld a compile error for the second case ("illegal forward reference&qu=
ot;) not be a more preferable?</p><p><br>I'm aware of '-Xcheckinit&=
#39; compiler option. But this introduces only *runtime* check and doesn=
9;t<br>prevent the code to compile.</p><p><br>There was a ticket <a href=3D=
"https://lampsvn.epfl.ch/trac/scala/ticket/399" rel=3D"nofollow" target=3D"=
_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dhtt=
ps%3A%2F%2Flampsvn.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz=
\x3d1\x26usg\x3dAFQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA';return true;" oncli=
ck=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Flampsv=
n.epfl.ch%2Ftrac%2Fscala%2Fticket%2F399\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNEwMKOcC4BAK6vxRdDNCzY6ARwrgA';return true;">https://lampsvn.epfl.c=
h/trac/<wbr>scala/ticket/399</a>, but it's closed. I cannot<br>understa=
nd the reason of closing (it cites one more example of such counterintuitiv=
e behavior but<br>doesn't explain why this behavior can't be change=
d).</p><p><br>Java handles a semantically analogous situation as 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<b=
r>=C2=A0 =C2=A0 =C2=A0 System.out.println("y: " + y); // Error: i=
llegal 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 find symbol var=
iable 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 fina=
l variables, and that generating bytecode<br>from Scala code is much more c=
omplicated (having in mind such things as unified access principle and<br>t=
herefore introducing methods for vals/vars, mapping of Scala's primary =
constructor to constructors<br>and initializers in Java, inheritance and ov=
erriding val->def->var, ...)</p><p>But, despite how complicated can b=
e the generated code, hopefully, might it be possible to detect<br>such for=
ward references in Scala parser and generate an error?</p><p><br><span><fon=
t color=3D"#888888">--<br>Regards,<br>Eugen<br></font></span></p><span><fon=
t 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></blockquot=
e></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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
W2H_ZtSgBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">scala-languag...@<wbr>googlegroups.com</a>.<br>
For more options, visit <a href=3D"https://groups.google.com/d/optout" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://grou=
ps.google.com/d/optout';return true;" onclick=3D"this.href=3D'https=
://groups.google.com/d/optout';return true;">https://groups.google.com/=
d/<wbr>optout</a>.<br>
</font></span></blockquote></div><br><br clear=3D"all"><div><br></div></div=
><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>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
W2H_ZtSgBgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:&=
#39;;return true;" onclick=3D"this.href=3D'javascript:';return true=
;">scala-languag...@<wbr>googlegroups.com</a>.<br>
For more options, visit <a href=3D"https://groups.google.com/d/optout" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://grou=
ps.google.com/d/optout';return true;" onclick=3D"this.href=3D'https=
://groups.google.com/d/optout';return true;">https://groups.google.com/=
d/<wbr>optout</a>.<br>
</blockquote></div>
</blockquote></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 />
------=_Part_4722_1883263192.1473600867820--
------=_Part_4721_1361046285.1473600867820--