Open xkr47 opened 6 years ago
A feature like this might be useful, but I don’t see what this has to do with the existing meaning of static
, and I don’t think we should copy C’s habit of reusing keywords for wildly different behavior here. If I saw a static
value in a function –
class C() {
void f() {
static variable Integer i = 0;
print(++i);
}
}
C c = C();
– then I would expect one of the following to be allowed:
Integer i = C.f.i;
Integer i = c.f.i;
Which one? No idea. (I suppose that’s the same as @jvasileff’s concern.)
I think it's interesting to explore reducing the differences between classes/objects and functions, and this feature (syntax aside) looks pretty neat. But, I wonder if it can be really justified.
Is memoizeNew
below that much better than memoizeOld
?
shared Result() memoizeOld<Result>(Result() f)
given Result satisfies Object {
variable Result? memo = null;
return () => memo = memo else f();
}
shared Result() memoizeNew<Result>(Result() f)
given Result satisfies Object => () {
static variable Result? memo = null;
return memo = memo else f();
};
Edit: for completeness, the curried form:
shared Result memoizeNew2<Result>(Result() f)()
given Result satisfies Object {
static variable Result? memo = null;
return memo = memo else f();
}
Doesn’t this have the same problems as classes did before constructors were a thing?
Like, the argument of the function (which is in scope) must not be referenced from the static
value’s specifier, which is awkward.
Vote for closure!
@Zambonifofex Could it be fixed the same way, then? A function with “constructors”, why not? It could even be a way to implement “overloaded” functions (whose types are perfectly expressible from the start).
// has type `Callable<Integer,[String]|[Boolean]>`
shared Integer sillyExample {
value magic = 3;
shared new (String s) {
return s.size * magic;
}
shared new (Boolean b) {
return if (b) then magic else 0;
}
}
P. S. Oops, I forgot overloading the default constructor in classes seems to not be allowed, my bad. But some analogous idea seems not that crazy, nonetheless.
@arseniiv, I thought about it myself, but I figured that, since Ceylon doesn’t have overloading (except within native("jvm")
), it’d only be right to allow named constructors, which don’t really make sense in functions.
I guess it could make sense to allow a single default “constructor” in functions:
Integer hmmm
{
static variable Integer foo = 0;
new (Integer i)
{
foo++;
return i + foo;
}
}
shared void run()
{
// In lambdas too:
foo(
function
{
static variable Integer foo = 0;
new (Integer i)
{
foo++;
return i + foo;
}
}
);
}
Unfortunately, this not only is kinda silly, but, for lambdas, it also collides with the syntax for #7190, which I have grown to like.
Sometimes it would be cool if functions could have static variables, which would be about the same as an object with fields and implementing a java Functional interface.
So I could do:
instead of
This was discussed in gitter; (hopefully correct) summary here: