- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
surprised by class initialization
Maybe Java has the same issue, but the way Scala constructors work
encourages me to put initialization code at the top of the body of
classes. Maybe this is a bad approach and I should put more
information into secondary constructors (def this = ).
scala> class Foo { val x = y + 2; val y = 3 }
defined class Foo
scala> (new Foo).x
res9: Int = 2
Whereas, when the assignment to y is first.
scala> class Bar { val y = 3; val x = y + 2 }
defined class Bar
scala> (new Bar).x
res2: Int = 5
The first example silently uses the default value for an int (0).
This is confusing to me because y is a val that takes on two different
values (0 and 3) during the initialization of the class. I remember a
similar problem when using initialization code in traits.
At the very least, should we be giving a compiler warning when
referring to a variable that has not yet been initialized?
Peace. Michael










Re: surprised by class initialization
>
> there's an example that shows that forward referencing vals can be useful.
> I quote:
>
> scala> val fib: Stream[Int] = 1 #:: ((0 #:: fib zip fib) map { case (x, y)
> => x + y })
> fib: Stream[Int] = Stream(1, ?)
>
> scala> fib take 10 toList
> res0: List[Int] = List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
>
> > (Perhaps, the last example should show an important usecase, but I can't
> > comprehend, sorry.)
>
> Cheers
>
> -- Martin- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
But this is a recursive function and fib is lazy initialized (but
still initialized). The initialization is within the statement and
after that it is used.
Here:
class Foo { val t = 1; val x = y + 2; val y = _ }
there is a eager forward reference of y across the statement boundary
(the semicolon). Or am I misreading something? Are those semicolons
not really statement separators?
I see it as an important difference.
But nevertheless I understand that it is a difficult problem to solve
otherwise Paul would have fixed it long time ago.
Re: Re: surprised by class initialization
I don't think your example is quite right.
class Foo {
private final int x;
private final int y;
Foo() {
x = y + 2;
y = 3;
}
}
> javac Foo.java
Foo.java:6: variable y might not have been initialized
x = y + 2;
Peace. Michael
On Wed, Nov 30, 2011 at 10:27 AM, Daniel Sobral wrote:
> On Wed, Nov 30, 2011 at 16:18, Dave wrote:
>> In java you get "illegal forward reference"
>>
>> It is a bug in 2.9
>> see: https://issues.scala-lang.org/browse/SI-4419
>
> No, that is a different issue. In this case, x and y are members of a
> class, so this code is valid. Java has the same problem, but the way
> this code would appear in Java is less obvious. Here's an equivalent
> Java class:
>
> class Foo {
> private int x;
> private int y;
>
> Foo() {
> x = y + 2;
> y = 3;
> }
> }
>
> Java won't complain, and it has the very same bug. I think all IDEs do
> complain about it, but Java initialization is much simpler than
> Scala's. But the point is that people find the bug in that obvious,
> while they don't find the bug in Scala version obvious. The reason is
> that Scala mixes declaration and initialization *in the syntax*, but
> separates them at run-time, while Java keeps them separated.
>
>>
>> On 30 nov, 18:22, Michael Schmitz wrote:
>>> Maybe Java has the same issue, but the way Scala constructors work
>>> encourages me to put initialization code at the top of the body of
>>> classes. Maybe this is a bad approach and I should put more
>>> information into secondary constructors (def this = ).
>>>
>>> scala> class Foo { val x = y + 2; val y = 3 }
>>> defined class Foo
>>>
>>> scala> (new Foo).x
>>> res9: Int = 2
>>>
>>> Whereas, when the assignment to y is first.
>>>
>>> scala> class Bar { val y = 3; val x = y + 2 }
>>> defined class Bar
>>>
>>> scala> (new Bar).x
>>> res2: Int = 5
>>>
>>> The first example silently uses the default value for an int (0).
>>> This is confusing to me because y is a val that takes on two different
>>> values (0 and 3) during the initialization of the class. I remember a
>>> similar problem when using initialization code in traits.
>>>
>>> At the very least, should we be giving a compiler warning when
>>> referring to a variable that has not yet been initialized?
>>>
>>> Peace. Michael
>>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>
Re: Re: surprised by class initialization
On Wed, Nov 30, 2011 at 16:41, Michael Schmitz wrote:
> I don't think your example is quite right.
>
> class Foo {
> private final int x;
> private final int y;
>
> Foo() {
> x = y + 2;
> y = 3;
> }
> }
>
>> javac Foo.java
> Foo.java:6: variable y might not have been initialized
> x = y + 2;
dcs@ayanami:~/tmp$ cat Foo.java
class Foo {
private int x;
private int y;
Foo() {
x = y + 2;
y = 3;
}
}
dcs@ayanami:~/tmp$ javac Foo.java
Are you using Java 7, by any chance?
Re: Re: surprised by class initialization
> javac -version
javac 1.6.0_22
I just stuck in the finals. Sorry I mean to make my change clearer
before sending the email.
Peace. Michael
On Wed, Nov 30, 2011 at 10:51 AM, Daniel Sobral wrote:
> On Wed, Nov 30, 2011 at 16:41, Michael Schmitz wrote:
>> I don't think your example is quite right.
>>
>> class Foo {
>> private final int x;
>> private final int y;
>>
>> Foo() {
>> x = y + 2;
>> y = 3;
>> }
>> }
>>
>>> javac Foo.java
>> Foo.java:6: variable y might not have been initialized
>> x = y + 2;
>
> dcs@ayanami:~/tmp$ cat Foo.java
> class Foo {
> private int x;
> private int y;
>
> Foo() {
> x = y + 2;
> y = 3;
> }
> }
>
>
> dcs@ayanami:~/tmp$ javac Foo.java
>
> Are you using Java 7, by any chance?
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>
Re: Re: surprised by class initialization
Yeah, just noticed that now.
On Wed, Nov 30, 2011 at 17:03, Michael Schmitz wrote:
>> javac -version
> javac 1.6.0_22
>
> I just stuck in the finals. Sorry I mean to make my change clearer
> before sending the email.
>
> Peace. Michael
>
>
> On Wed, Nov 30, 2011 at 10:51 AM, Daniel Sobral wrote:
>> On Wed, Nov 30, 2011 at 16:41, Michael Schmitz wrote:
>>> I don't think your example is quite right.
>>>
>>> class Foo {
>>> private final int x;
>>> private final int y;
>>>
>>> Foo() {
>>> x = y + 2;
>>> y = 3;
>>> }
>>> }
>>>
>>>> javac Foo.java
>>> Foo.java:6: variable y might not have been initialized
>>> x = y + 2;
>>
>> dcs@ayanami:~/tmp$ cat Foo.java
>> class Foo {
>> private int x;
>> private int y;
>>
>> Foo() {
>> x = y + 2;
>> y = 3;
>> }
>> }
>>
>>
>> dcs@ayanami:~/tmp$ javac Foo.java
>>
>> Are you using Java 7, by any chance?
>>
>>
>> --
>> Daniel C. Sobral
>>
>> I travel to the future all the time.
>>
>
Re: Re: surprised by class initialization
On Wed, Nov 30, 2011 at 7:51 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
I think you need to write
Foo() { x = this.y + 2 y = 3 }
That's pretty much what Scala's version translates to.
Cheers
-- Martin
Re: Re: surprised by class initialization
Is there a reason why the Java compiler allows the forward reference, when prefixing with "this"? It seems the compile error, which occurs without "this", is valid, and I'm struggling to think of a use case, where the above behavior is desirable.