Lazily Initialized Variables that are Compatible with const/immutable
Timon Gehr
timon.gehr at gmx.ch
Sat Nov 19 00:18:04 UTC 2022
On 18.11.22 18:22, Vijay Nayar wrote:
> On Friday, 18 November 2022 at 11:06:44 UTC, Timon Gehr wrote:
>> On 18.11.22 11:59, Timon Gehr wrote:
>>>
>>>
>>>> which is used to optimize performance (in Dart, `const` is closer to
>>>> D's `immutable`).
>>>
>>> Actually, it is closer to `static immutable`.
>>
>> (But even that analogy has significant limitations, e.g., transitivity
>> of Dart `const` is often checked at runtime, even if it is completely
>> obvious during type checking that an assignment is not going to work.)
>
> It's not as complicated as you are making it out to be.
I don't understand what you think is complicated. Everything I wrote was
true. The issue was that in your post you were conflating concepts in D
and Dart that are only superficially similar.
Anyway, by all means, go ahead and create a DIP for lazy initialization.
I have proposed this exact thing (with lazy keyword and all) in the
past, but it never really caught on. (And frankly, it _would_ be
confusing if for fields "lazy" actually meant lazy while for function
parameters it still means "by name"...)
> The purpose of Dart's late variables is as they describe:
>
I am very much aware of the purpose of lazy initialization. It's one
reason for my recommendation to avoid D's mutability qualifiers if any
kind of abstraction is involved. The mutability qualifiers break
abstractions.
Anyway, Dart is not actually providing anything that you can't have in
D. It does not actually have transitive `const` and `immutable`
qualifiers. Those are the issue. If you don't use them you can use the
same patterns as in Dart, just with different syntax.
> ...
>
> There are many cases where lazy initialization can be used to avoid
> costly setup, but currently in D, if you use lazy initialization, you
> must immediately rewrite all your code
Not if you avoided qualifiers. (As I do.)
> and avoid ever using `const`,
Yes, that was my point. Lazy initialization is not the only common
pattern that the qualifiers prevent. Don't use them unless you know
exactly what you are doing and will want to do in the future. (So very
infrequently or at least in very special circumstances.)
> because it might trigger initialization of lazy variables. This is
> especially silly for functions like "print" or "writeToDisk", which
> absolutely do not modify the classes at hand.
That's a weird way to put it because they do actually modify memory
during late initialization and `const` prevents you from doing it. Don't
use `const` if that's not what you want. Probably you want what's
sometimes called "logical const", but that's not a feature in D.
In your OP, you asked the question "Is there another way to perform lazy
initialization that is compatible with const/immutable, or is this
needed as a language feature?"
You'd need to change the language to do what you want, but just adding
built-in support for lazy initialization would not actually fix the more
general problem. Mutation of memory is often an implementation detail,
not just for lazy initialization. You'd probably just run into some
other roadblock further down the line. And any hack you do in your own
code to work around the strictness of qualifiers leads to undefined
behavior. It's just not worth the hassle.
More information about the Digitalmars-d
mailing list