- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: Question about constructor logic
Mon, 2009-03-23, 15:16
>>>>> "Silvio" == Silvio Bierman writes:
Silvio> So far so good. But what happens with "upper" which was a local
Silvio> variable to the constructor in Java (and therefore not part of
Silvio> the MyClass instance) in the Scala case? Will each MyClass
Silvio> instance hold three fields or does the compiler detect that
Silvio> "upper" is only needed temporarily?
The compiler won't detect that. But you can do:
class MyClass(f:String) {
private val (field1,field2) = {
val upper = f.toUpperCase
(upper.substring(0,4),upper.substring(4))
}
...
}
Mon, 2009-03-23, 15:47
#2
Re: Question about constructor logic
On Monday March 23 2009, Seth Tisue wrote:
> >>>>> "Silvio" == Silvio Bierman
> >>>>> writes:
>
> Silvio> So far so good. But what happens with "upper" which was a
> local Silvio> variable to the constructor in Java (and therefore not
> part of Silvio> the MyClass instance) in the Scala case? Will each
> MyClass Silvio> instance hold three fields or does the compiler
> detect that Silvio> "upper" is only needed temporarily?
>
> The compiler won't detect that. But you can do:
>
> class MyClass(f:String) {
> private val (field1,field2) = {
> val upper = f.toUpperCase
> (upper.substring(0,4),upper.substring(4))
> }
> ...
> }
No. We established empirically that even when written like this, the
tuple used "temporarily" in the private val definition will be retained
in the generated class.
Randall Schulz
Mon, 2009-03-23, 16:07
#3
Re: Question about constructor logic
On Monday March 23 2009, Seth Tisue wrote:
> >>>>> "Randall" == Randall R Schulz writes:
>
> Randall> No. We established empirically that even when written like
> Randall> this, the tuple used "temporarily" in the private val
> Randall> definition will be retained in the generated class.
>
> I missed that. Seems like a bug. Is there a ticket on it?
I was told not to file one unless I had a recommended solution
(it's all in the thread I referred to earlier).
Randall Schulz
Mon, 2009-03-23, 17:17
#4
Re: Question about constructor logic
On Mon, Mar 23, 2009 at 2:40 PM, Randall R Schulz wrote:
> On Monday March 23 2009, Seth Tisue wrote:
>> >>>>> "Randall" == Randall R Schulz writes:
>>
>> Randall> No. We established empirically that even when written like
>> Randall> this, the tuple used "temporarily" in the private val
>> Randall> definition will be retained in the generated class.
>>
>> I missed that. Seems like a bug. Is there a ticket on it?
>
> I was told not to file one unless I had a recommended solution
> (it's all in the thread I referred to earlier).
The recommended solution is to simply use a constructor-local variable
for the tuple. However, Martin's response was:
"Please don't file a bug without proposing an alternative. The spec
explains how tuple assignemnts are expanded. If you know a better way,
please suggest a patch."
A patch is a bit more than just suggesting an alternative. As far as I
am concerned this is an obvious optimisation with no user-visible
downsides and it would make sense to have it tracked as an enhancement
request in Trac. Then someone like paulp might come along and fix it
for us. ;) I don't set the rules though.
Best,
Ismael
Mon, 2009-03-23, 22:57
#5
Re: Question about constructor logic
I think the "local" keyword suggestion was prompted by Martin requesting that a ticket not be created without a workable suggestion and preferably a patch. I suspect that just because the information can be inferred doesn't mean that it is available at the right stage of compilation to be useful without dirty tricks. But the compiler is beyond me, so I don't really know.
But, like I said, the "local" keyword would allow you to ensure that a variable that was intended to be local to the constructor would not escape into the fully constructed object. That would me references in methods (and other places) would be compile time errors. From a programmer perspective I can see the benefit, just like with the @tailrec annotation. I'm telling the compiler to ensure that some property of my code is true, and reject my code if it's not.
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
--
http://erikengbrecht.blogspot.com/
But, like I said, the "local" keyword would allow you to ensure that a variable that was intended to be local to the constructor would not escape into the fully constructed object. That would me references in methods (and other places) would be compile time errors. From a programmer perspective I can see the benefit, just like with the @tailrec annotation. I'm telling the compiler to ensure that some property of my code is true, and reject my code if it's not.
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Right, so if a method doesn't access the variable, you should get GC and bloatlessness implicitly, and if it does, then there's no way around it, so what do you gain by an explicit keyword or annotation?In what scenario is there not enough information for the compiler to figure out what you want?
On Mon, Mar 23, 2009 at 5:39 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:Because you're using a temporary variable, and you (1) want the object to which it refers to be GC'd when you're done, and (2) you don't want to bloat your object with extra fields.
I would classify a "local" annotation (err...keyword) in the same group with the @tailrec annotation paulp recently added to trunk. The runtime characteristics of your program are potentially very different if the reference is retained, so you want to ensure that it isn't. Just like a non-tail recursive method and a tail recursive method have very different characteristics.
Otherwise I think the compiler implementing the optimization would be sufficient.
On Mon, Mar 23, 2009 at 5:32 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
So why would you want to prevent that?
On Mon, Mar 23, 2009 at 5:30 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
If the variable is referred to in a method, then the variable has to be stored on the object so that the method can use it. If the variable isn't put on the object, then the referencing method won't even compile.
On Mon, Mar 23, 2009 at 5:27 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:What am asking is, what's the importance of not being referred to in a method?
On Mon, Mar 23, 2009 at 5:23 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Mon, Mar 23, 2009 at 2:02 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Why would you want that? The idea is that a constructor is as if the the class body is executable. Variables are potential fields, unless the compiler decides it can get away with optimizing them away, What's wrong with this approach?
It's not a big issue either way, but making the local nature of the variable explicit seems more or less consistent with the overall philosophy of Scala.
Why does Scala allow immutables to be explicitly declared as "val"? Because it guarantees that the value will not change. Scala does not just let the compiler figure out that the value never changes. Similarly, declaring a temp variable or value in the constructor as "local" would guarantee that it is not used anywhere outside the constructor.
Again, I don't consider this a major issue, so I'll drop it now that I've made my point.
Russ P.
On Mon, Mar 23, 2009 at 4:58 PM, Russ Paielli <russ.paielli@gmail.com> wrote:In that case, why not let the programmer explicitly declare his intent to make the variable (or val) "local" rather than letting the compiler figure it out. If you leave it to the compiler, some other programmer may come along and use the variable (not realizing that it was supposed to be local), in which case the variable is now included in every instance of the class, thus violating the intent of the original programmer.
Russ P.
On Mon, Mar 23, 2009 at 1:13 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
That is what it means, but the point is that if you tell the compiler that the "field" can only be accessed from this instance, and the compiler sees that no method is accessing it, the compiler can figure out that it can be implemented as a local variable in the constructor.
On Mon, Mar 23, 2009 at 4:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:I don't know where the syntax "private[this]" comes from, but it seems misleading to me. If I saw it for the first time, I would assume that the variable is private to "this", which means a regular "private" variable. That's exactly what is *not* supposed to be. I think "local" makes more sense. But maybe I'm missing something.
Russ P.
On Mon, Mar 23, 2009 at 10:52 AM, Arthur Peters <arthur.peters@gmail.com> wrote:
I think that keyword is not "local" but "private[this]". This is discussed a bit in the previous thread ( http://www.nabble.com/Temporary-Values-in-Constructors-Retained-As-Fields-td22526316.html#a22526316 )
--
http://RussP.us
--
http://RussP.us
--
http://erikengbrecht.blogspot.com/
--
http://erikengbrecht.blogspot.com/
--
http://erikengbrecht.blogspot.com/
Mon, 2009-03-23, 23:07
#6
Re: Question about constructor logic
I think people are trying to point out that it would be nice to be able to specify that a member should only be used in the constructor. That way the compiler will raise an error if it is accidentally used in a method.
This is similar to tail-recursion. The compiler can fully detect tail recursiveness, too. But it's nice to be able to have the compiler tell you when you make a mistake and break the optimization.
-Arthur
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
This is similar to tail-recursion. The compiler can fully detect tail recursiveness, too. But it's nice to be able to have the compiler tell you when you make a mistake and break the optimization.
-Arthur
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Right, so if a method doesn't access the variable, you should get GC and bloatlessness implicitly, and if it does, then there's no way around it, so what do you gain by an explicit keyword or annotation?In what scenario is there not enough information for the compiler to figure out what you want?
On Mon, Mar 23, 2009 at 5:39 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:Because you're using a temporary variable, and you (1) want the object to which it refers to be GC'd when you're done, and (2) you don't want to bloat your object with extra fields.
I would classify a "local" annotation (err...keyword) in the same group with the @tailrec annotation paulp recently added to trunk. The runtime characteristics of your program are potentially very different if the reference is retained, so you want to ensure that it isn't. Just like a non-tail recursive method and a tail recursive method have very different characteristics.
Otherwise I think the compiler implementing the optimization would be sufficient.
On Mon, Mar 23, 2009 at 5:32 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
So why would you want to prevent that?
On Mon, Mar 23, 2009 at 5:30 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
If the variable is referred to in a method, then the variable has to be stored on the object so that the method can use it. If the variable isn't put on the object, then the referencing method won't even compile.
On Mon, Mar 23, 2009 at 5:27 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:What am asking is, what's the importance of not being referred to in a method?
On Mon, Mar 23, 2009 at 5:23 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Mon, Mar 23, 2009 at 2:02 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Why would you want that? The idea is that a constructor is as if the the class body is executable. Variables are potential fields, unless the compiler decides it can get away with optimizing them away, What's wrong with this approach?
It's not a big issue either way, but making the local nature of the variable explicit seems more or less consistent with the overall philosophy of Scala.
Why does Scala allow immutables to be explicitly declared as "val"? Because it guarantees that the value will not change. Scala does not just let the compiler figure out that the value never changes. Similarly, declaring a temp variable or value in the constructor as "local" would guarantee that it is not used anywhere outside the constructor.
Again, I don't consider this a major issue, so I'll drop it now that I've made my point.
Russ P.
On Mon, Mar 23, 2009 at 4:58 PM, Russ Paielli <russ.paielli@gmail.com> wrote:In that case, why not let the programmer explicitly declare his intent to make the variable (or val) "local" rather than letting the compiler figure it out. If you leave it to the compiler, some other programmer may come along and use the variable (not realizing that it was supposed to be local), in which case the variable is now included in every instance of the class, thus violating the intent of the original programmer.
Russ P.
On Mon, Mar 23, 2009 at 1:13 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
That is what it means, but the point is that if you tell the compiler that the "field" can only be accessed from this instance, and the compiler sees that no method is accessing it, the compiler can figure out that it can be implemented as a local variable in the constructor.
On Mon, Mar 23, 2009 at 4:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:I don't know where the syntax "private[this]" comes from, but it seems misleading to me. If I saw it for the first time, I would assume that the variable is private to "this", which means a regular "private" variable. That's exactly what is *not* supposed to be. I think "local" makes more sense. But maybe I'm missing something.
Russ P.
On Mon, Mar 23, 2009 at 10:52 AM, Arthur Peters <arthur.peters@gmail.com> wrote:
I think that keyword is not "local" but "private[this]". This is discussed a bit in the previous thread ( http://www.nabble.com/Temporary-Values-in-Constructors-Retained-As-Fields-td22526316.html#a22526316 )
--
http://RussP.us
--
http://RussP.us
--
http://erikengbrecht.blogspot.com/
--
http://erikengbrecht.blogspot.com/
Mon, 2009-03-23, 23:07
#7
Re: Question about constructor logic
On second thought, this could be a scenario: The method only needs one property of the object. The compiler will remind you to assign that property to a separate field, which the method gets to access, while the object as a whole can be garbage collected etc. (Doesn't help the "bloat" point.)
On Mon, Mar 23, 2009 at 5:54 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
On Mon, Mar 23, 2009 at 5:54 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
I hear that, but in the case of tail recursion, when you get the error you can say, "I still want the optimization," and reorganize the code so that it accomplishes what you want it to accomplish without breaking tail recursion. But if a method needs to access a value that is declared in the constructor, how many choices do you have? If the compiler flags it as an error, you have two choices: Forget your plans to have the method access it, or delete the annotation. What am I missing?
On Mon, Mar 23, 2009 at 5:49 PM, Arthur Peters <arthur.peters@gmail.com> wrote:I think people are trying to point out that it would be nice to be able to specify that a member should only be used in the constructor. That way the compiler will raise an error if it is accidentally used in a method.
This is similar to tail-recursion. The compiler can fully detect tail recursiveness, too. But it's nice to be able to have the compiler tell you when you make a mistake and break the optimization.
-Arthur
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:Right, so if a method doesn't access the variable, you should get GC and bloatlessness implicitly, and if it does, then there's no way around it, so what do you gain by an explicit keyword or annotation?In what scenario is there not enough information for the compiler to figure out what you want?
On Mon, Mar 23, 2009 at 5:39 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:Because you're using a temporary variable, and you (1) want the object to which it refers to be GC'd when you're done, and (2) you don't want to bloat your object with extra fields.
I would classify a "local" annotation (err...keyword) in the same group with the @tailrec annotation paulp recently added to trunk. The runtime characteristics of your program are potentially very different if the reference is retained, so you want to ensure that it isn't. Just like a non-tail recursive method and a tail recursive method have very different characteristics.
Otherwise I think the compiler implementing the optimization would be sufficient.
On Mon, Mar 23, 2009 at 5:32 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
So why would you want to prevent that?
On Mon, Mar 23, 2009 at 5:30 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
If the variable is referred to in a method, then the variable has to be stored on the object so that the method can use it. If the variable isn't put on the object, then the referencing method won't even compile.
On Mon, Mar 23, 2009 at 5:27 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:What am asking is, what's the importance of not being referred to in a method?
On Mon, Mar 23, 2009 at 5:23 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Mon, Mar 23, 2009 at 2:02 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Why would you want that? The idea is that a constructor is as if the the class body is executable. Variables are potential fields, unless the compiler decides it can get away with optimizing them away, What's wrong with this approach?
It's not a big issue either way, but making the local nature of the variable explicit seems more or less consistent with the overall philosophy of Scala.
Why does Scala allow immutables to be explicitly declared as "val"? Because it guarantees that the value will not change. Scala does not just let the compiler figure out that the value never changes. Similarly, declaring a temp variable or value in the constructor as "local" would guarantee that it is not used anywhere outside the constructor.
Again, I don't consider this a major issue, so I'll drop it now that I've made my point.
Russ P.
On Mon, Mar 23, 2009 at 4:58 PM, Russ Paielli <russ.paielli@gmail.com> wrote:In that case, why not let the programmer explicitly declare his intent to make the variable (or val) "local" rather than letting the compiler figure it out. If you leave it to the compiler, some other programmer may come along and use the variable (not realizing that it was supposed to be local), in which case the variable is now included in every instance of the class, thus violating the intent of the original programmer.
Russ P.
On Mon, Mar 23, 2009 at 1:13 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
That is what it means, but the point is that if you tell the compiler that the "field" can only be accessed from this instance, and the compiler sees that no method is accessing it, the compiler can figure out that it can be implemented as a local variable in the constructor.
On Mon, Mar 23, 2009 at 4:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:I don't know where the syntax "private[this]" comes from, but it seems misleading to me. If I saw it for the first time, I would assume that the variable is private to "this", which means a regular "private" variable. That's exactly what is *not* supposed to be. I think "local" makes more sense. But maybe I'm missing something.
Russ P.
On Mon, Mar 23, 2009 at 10:52 AM, Arthur Peters <arthur.peters@gmail.com> wrote:
I think that keyword is not "local" but "private[this]". This is discussed a bit in the previous thread ( http://www.nabble.com/Temporary-Values-in-Constructors-Retained-As-Fields-td22526316.html#a22526316 )
--
http://RussP.us
--
http://RussP.us
--
http://erikengbrecht.blogspot.com/
--
http://erikengbrecht.blogspot.com/
Mon, 2009-03-23, 23:27
#8
Re: Question about constructor logic
I hear that, but in the case of tail recursion, when you get the error you can say, "I still want the optimization," and reorganize the code so that it accomplishes what you want it to accomplish without breaking tail recursion. But if a method needs to access a value that is declared in the constructor, how many choices do you have? If the compiler flags it as an error, you have two choices: Forget your plans to have the method access it, or delete the annotation. What am I missing?
On Mon, Mar 23, 2009 at 5:49 PM, Arthur Peters <arthur.peters@gmail.com> wrote:
On Mon, Mar 23, 2009 at 5:49 PM, Arthur Peters <arthur.peters@gmail.com> wrote:
I think people are trying to point out that it would be nice to be able to specify that a member should only be used in the constructor. That way the compiler will raise an error if it is accidentally used in a method.
This is similar to tail-recursion. The compiler can fully detect tail recursiveness, too. But it's nice to be able to have the compiler tell you when you make a mistake and break the optimization.
-Arthur
On Mon, Mar 23, 2009 at 5:44 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:Right, so if a method doesn't access the variable, you should get GC and bloatlessness implicitly, and if it does, then there's no way around it, so what do you gain by an explicit keyword or annotation?In what scenario is there not enough information for the compiler to figure out what you want?
On Mon, Mar 23, 2009 at 5:39 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:Because you're using a temporary variable, and you (1) want the object to which it refers to be GC'd when you're done, and (2) you don't want to bloat your object with extra fields.
I would classify a "local" annotation (err...keyword) in the same group with the @tailrec annotation paulp recently added to trunk. The runtime characteristics of your program are potentially very different if the reference is retained, so you want to ensure that it isn't. Just like a non-tail recursive method and a tail recursive method have very different characteristics.
Otherwise I think the compiler implementing the optimization would be sufficient.
On Mon, Mar 23, 2009 at 5:32 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
So why would you want to prevent that?
On Mon, Mar 23, 2009 at 5:30 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
If the variable is referred to in a method, then the variable has to be stored on the object so that the method can use it. If the variable isn't put on the object, then the referencing method won't even compile.
On Mon, Mar 23, 2009 at 5:27 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:What am asking is, what's the importance of not being referred to in a method?
On Mon, Mar 23, 2009 at 5:23 PM, Russ Paielli <russ.paielli@gmail.com> wrote:
On Mon, Mar 23, 2009 at 2:02 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
Why would you want that? The idea is that a constructor is as if the the class body is executable. Variables are potential fields, unless the compiler decides it can get away with optimizing them away, What's wrong with this approach?
It's not a big issue either way, but making the local nature of the variable explicit seems more or less consistent with the overall philosophy of Scala.
Why does Scala allow immutables to be explicitly declared as "val"? Because it guarantees that the value will not change. Scala does not just let the compiler figure out that the value never changes. Similarly, declaring a temp variable or value in the constructor as "local" would guarantee that it is not used anywhere outside the constructor.
Again, I don't consider this a major issue, so I'll drop it now that I've made my point.
Russ P.
On Mon, Mar 23, 2009 at 4:58 PM, Russ Paielli <russ.paielli@gmail.com> wrote:In that case, why not let the programmer explicitly declare his intent to make the variable (or val) "local" rather than letting the compiler figure it out. If you leave it to the compiler, some other programmer may come along and use the variable (not realizing that it was supposed to be local), in which case the variable is now included in every instance of the class, thus violating the intent of the original programmer.
Russ P.
On Mon, Mar 23, 2009 at 1:13 PM, Naftoli Gugenheim <naftoligug@gmail.com> wrote:
That is what it means, but the point is that if you tell the compiler that the "field" can only be accessed from this instance, and the compiler sees that no method is accessing it, the compiler can figure out that it can be implemented as a local variable in the constructor.
On Mon, Mar 23, 2009 at 4:07 PM, Russ Paielli <russ.paielli@gmail.com> wrote:I don't know where the syntax "private[this]" comes from, but it seems misleading to me. If I saw it for the first time, I would assume that the variable is private to "this", which means a regular "private" variable. That's exactly what is *not* supposed to be. I think "local" makes more sense. But maybe I'm missing something.
Russ P.
On Mon, Mar 23, 2009 at 10:52 AM, Arthur Peters <arthur.peters@gmail.com> wrote:
I think that keyword is not "local" but "private[this]". This is discussed a bit in the previous thread ( http://www.nabble.com/Temporary-Values-in-Constructors-Retained-As-Fields-td22526316.html#a22526316 )
--
http://RussP.us
--
http://RussP.us
--
http://erikengbrecht.blogspot.com/
--
http://erikengbrecht.blogspot.com/
>>>>> "Randall" == Randall R Schulz writes:
Randall> No. We established empirically that even when written like
Randall> this, the tuple used "temporarily" in the private val
Randall> definition will be retained in the generated class.
I missed that. Seems like a bug. Is there a ticket on it?