Why exists restriction: once methods must not be declared within a const class?
Because a once method in a const class isn't necessarily immutable and thread-safe unless we can safely compute the result in an atomic manner. But that requires locks which introduces all sorts of nastiness. So up until now I've just disallowed it (although eventually I'd like to define a safe design so maybe we can have that feature).
In Scala exists methods getOrElseUpdate. It's usefull for methods that remember his returns.
I am open to adding something like that to map. Although it is potentially inefficient since we have to evaluate the default expression no matter. I suspect that Scala makes that parameter a lazy expression? I'd like to hear some other feedback what other people think.
What do you think about "Extension Methods"?
I think that we need this, but I do not want to tackle for 1.0 (I want to let existing feature set settle down). The way I currently like best is how C# does it (with static methods where first param is notated with this keyword):
class StrUtil
{
static Str truncate(this Str s, Int width) {...}
}
AkcelistoMon 21 Sep 2009
I suspect that Scala makes that parameter a lazy expression?
Yes. I am not noticed. Second parameter is "call-by-name".
May be so:
//in Map
V getOrUpdate(K key, |->V| value)
// calling
picts.getOrUpdate(name)|,|{Pict(name)}
brianMon 21 Sep 2009
Good idea. So let's propose this new method on Map:
V getOrAdd(K key, |K->V| val)
Having it pass the key in the function is probably a little more useful and allows it-blocks (which require one parameter):
> Why exists restriction: once methods must not be declared within a const class? > Because a once method in a const class isn't necessarily immutable and thread-safe unless we can safely compute the result in an atomic manner.
You can add a once method equivalent to Java using volatile variables, no locking required. The key thing is that the method should only refer to const instance variables and other constants. That way the result is always the same, so it doesn't matter whether the code gets run more than once (ie. the once keyword simply means that the result should be cached, as per Java String hashCode).
brianWed 23 Sep 2009
You can add a once method equivalent to Java using volatile variables, no locking required.
True, although as you said there would be no guarantee that the method was truly executed only once without a lock. I think we can live with that.
But we can't really guarantee that the function only references other const instance fields. You might call other once methods or use dynamic invoke.
jodastephenThu 24 Sep 2009
Instance fields are either const, non-const or once for this discussion. The const ones are fine to call. The non-const ones don't exist (its a const class we're discussing).
The once ones should also be fine - a once field that calls another once field will just cause that field to be initialised.
So, you'd just need to block dynamic invoke, which shouldn't be too hard.
Akcelisto Sun 20 Sep 2009
brian Sun 20 Sep 2009
@Akcelisto - thanks for your feedback!
Because a once method in a const class isn't necessarily immutable and thread-safe unless we can safely compute the result in an atomic manner. But that requires locks which introduces all sorts of nastiness. So up until now I've just disallowed it (although eventually I'd like to define a safe design so maybe we can have that feature).
I am open to adding something like that to map. Although it is potentially inefficient since we have to evaluate the default expression no matter. I suspect that Scala makes that parameter a lazy expression? I'd like to hear some other feedback what other people think.
I think that we need this, but I do not want to tackle for 1.0 (I want to let existing feature set settle down). The way I currently like best is how C# does it (with static methods where first param is notated with
this
keyword):Akcelisto Mon 21 Sep 2009
Yes. I am not noticed. Second parameter is "call-by-name".
May be so:
brian Mon 21 Sep 2009
Good idea. So let's propose this new method on Map:
Having it pass the key in the function is probably a little more useful and allows it-blocks (which require one parameter):
andy Mon 21 Sep 2009
+1 - that seems useful.
brian Wed 23 Sep 2009
done!
changeset
jodastephen Wed 23 Sep 2009
You can add a once method equivalent to Java using volatile variables, no locking required. The key thing is that the method should only refer to const instance variables and other constants. That way the result is always the same, so it doesn't matter whether the code gets run more than once (ie. the
once
keyword simply means that the result should be cached, as per Java String hashCode).brian Wed 23 Sep 2009
True, although as you said there would be no guarantee that the method was truly executed only once without a lock. I think we can live with that.
But we can't really guarantee that the function only references other const instance fields. You might call other once methods or use dynamic invoke.
jodastephen Thu 24 Sep 2009
Instance fields are either const, non-const or once for this discussion. The
const
ones are fine to call. The non-const ones don't exist (its a const class we're discussing).The
once
ones should also be fine - aonce
field that calls anotheronce
field will just cause that field to be initialised.So, you'd just need to block dynamic invoke, which shouldn't be too hard.