[Issue 24030] New: A `lazy` parameter shouldn't be allowed to be "called" twice
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Jul 4 12:35:34 UTC 2023
https://issues.dlang.org/show_bug.cgi?id=24030
Issue ID: 24030
Summary: A `lazy` parameter shouldn't be allowed to be "called"
twice
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: qs.il.paperinik at gmail.com
It’s quite straightforward: The intended use for `lazy` is to defer evaluation;
everyone seeing this for the first time expects that. The fact that a function
taking a `lazy` parameter may evaluate the underlying delegate more than once
is surprising. Only once a programmer learns that there is a delegate
underlying, it makes some sense.
This is a breaking change, but there’s a simple transition path: Use a delegate
explicitly, and you’ll surprise nobody.
Checking that a `lazy` parameter is evaluated at most once only needs a very
limited form of control-flow analysis. In `@system` code, this could be ignored
and calling a `lazy` parameter more than once becomes Undefined Behavior.
If desired, on non-release builds, the only-call-once rule can be asserted by
introducing a hidden `bool` variable on the caller’s side:
```d
int f(lazy int);
1 + f(1);
```
is lowered to:
```d
int f(int delegate());
bool called; // unique name
1 + f({
assert(!called);
called = true;
return 1;
});
```
What about `lazy` `void` parameters?
They’re no different. You’re after the side-effect, but again, getting it more
than once will be surprising; use a delegate.
--
More information about the Digitalmars-d-bugs
mailing list