-
Notifications
You must be signed in to change notification settings - Fork 62
Attribute lazy initialization #3544
Comments
[@matejonnet] Or even shorter if it is possible to do something like this:
"?=" will cause that createFoo() is called on first usage of foo. |
[@RossTate] The non-variable version is bad cuz you're accessing a value before it's been initialized.
would be bad because between
|
[@luolong]
|
[@gavinking] So, @matejonnet has a point here. The simplest I was able to get was the following:
which sorta took me by surprise. It's a bit better than what @matejonnet writes above, but it's still unacceptably verbose. The big problem here is that, ages ago, @FroMage asked me to change the type of assignment expressions like
Which I think would be acceptable, no? @FroMage WDYT, can we change this back? |
[@gavinking]
where |
[@FroMage] I'd like a way to define lazy memoised attributes, I've already made that clear. Perhaps I think that Integer computeVal() => ... ;
cached shared Integer val => computeVal(); I mean, if we introduce |
[@quintesse] |
[@gavinking] FTR, I'm not advocating I'm also not against eventually introducing a Fantom-style |
[@FroMage] Fair enough, but changing the type of |
Only when:
|
[@FroMage] Sure. |
[@RossTate] Lazy actually typically means memoized. A while back I had proposed that Lazy foo = {compute()}; foo.eval On Thursday, January 3, 2013, Stéphane Épardaud wrote:
|
[@gavinking] I have made that change to the type of
Now reducing issue priority and shifting out of Ceylon 1.0. We can re-discuss this stuff for a future version. |
[@gavinking] P.S. the backend needs to be fixed to support this change to the semantics of a nested assignment operator. |
[@quintesse] I see this has been suggested for 1.5 but I've already encountered several times wanting something like this. Maybe we could move it a bit forward to 1.3? It doesn't seem too hard too implement but can still quite useful. Of course Gavin's 2-liner is not too bad, but nothing can beat:
|
[@xkr47] I also vote for |
[@kelvio] Why not "shared lazy Integer val => computeVal();"?
|
[@kelvio] Got it. 2015-11-02 10:24 GMT-02:00 Jonas Berlin [email protected]:
Atenciosamente, Kelvio Matias Santos Silva. |
[@gavinking] I like |
[@quintesse] +1 on |
[@bjansen] But "once" is an adverb, and you decided to use adjectives for annotations, as stated in the faq:
|
[@xkr47] Somehow I feel that |
[@luolong] maybe we should borrow from the functional languages terminology and call it |
[@luolong] so the example would read like this: shared memoized Integer val => computeVal(); |
[@ncorai]
While using a verb in a Ceylon annotation seems a big no-no, I think people would accomodate the use of an adverb. |
[@gdejohn] 👍 for |
[@lukedegruchy] I vote for cached. |
By the way, I’m not saying that I agree with @gavinking here, I agree with @lucaswerkmeister in that this feels counterintuitive, and that I’d rather have that kind of code rejected by the type‐checker. That’s exactly why I think there should be a different annotation: because the semantics are very different from each other. |
Has it been determined if |
@quintesse I would also strongly object to that interpretation. |
@lucaswerkmeister not saying I don't agree with you, but a good reason as to why you strongly object would be nice :) |
What @quintesse said is the interpretation I favor. That way the specifier defines a default value that is used if you never assign it anywhere else. Sorta but not exactly like defaulted parameters. |
And the reason I favor this interpretation is that it gives 'late' a more consistent behavior between the two cases. |
Which is fine, and I appreciate that. But @lucaswerkmeister has a good practical point which is that very often people want to lazily initialize a value without allowing the possibility for a client to overrule that value. So maybe it is a mistake to try to squeeze those semantics into |
@quintesse well, I already said it above – I see this feature as a way to defer initialization while still remaining in control of it (my class doesn’t rely on someone else calling an |
Perhaps, but frankly I don't find it very appealing to introduce a new annotation that is in so many other respects so extremely semantically similar to |
I honestly can’t see how it’s I don’t think trying to merge those two behaviors into one single annotation would be a good idea. If you want the behavior you are describing, you’d annotate the value as |
They're very similar in how they affect definite assignment checking and determination of where the initializer section ends. This is, of course, the most interesting thing about these annotations.
That's just not true at all. |
Sure.
I don’t understand. By @lucaswerkmeister’s definition,
I can’t speak for the implementation, but I definitely feel like they’d do completely different things. And if you could exemplify how you think the spec would be, and how the two behaviors would overlap, it’d great (I’m trying to convince myself that they are similar and failing; if you could do that, that’s what would be great). |
That is not the definition that I have implemented!
No, that's just not the current semantics!
Here's how I implemented the typechecker part of this: @eb5b3b8ed5f6c36a7642e2511e1b63b7e09ab68f. Note that I deleted more code than I added. It made the typechecker simpler.
I don't care about vague feelings. I care about objectively measurable things.
The spec change is trivial as hell:
That's it, AFAICS. |
I understand this concern, and I'm sympathetic to it, but OTOH, it's quite trivial to get the behavior you're looking for: late value _thing = Thing();
shared Thing thing => _thing; This way, you avoid sharing the "assignability" of Furthermore, if you happen to be implementing an API interface, you don't even need to do that. |
Note that what attracted me to this whole solution was how tiny of a change it was to the Ceylon language. I got to piggyback/reuse the existing behavior of something that already existed for a long time. |
Well, I agree that, by your definition, it’s really similar to
I’m saying that they are considered as assignable by the compiler. I know trying to assign them more than once would result in an error at run‐time.
Under your definition. Under @lucaswerkmeister’s definition (the one I strongly prefer), this simply wouldn’t be the case. I think your definition would simply not be that useful. When will someone actually prefer to allow their interface user to actually override their given memoized value? When will that actually be better than @lucaswerkmeister’s definition? |
@gavinking fixed. If we want to change the semantics of |
Thanks Tom.
Yeah, let me reflect on this. If we do, it's just a typechecker change. |
[@matejonnet] Looking for a shorter way to initialize an object attribute on a first use,
and ability to use immutable attribute instead of variable
I would like to write this as:
[Migrated from ceylon/ceylon-spec#438]
The text was updated successfully, but these errors were encountered: