Bug 24030 – A `lazy` parameter shouldn't be allowed to be "called" twice

Status
NEW
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-07-04T12:35:34Z
Last change time
2024-12-13T19:30:01Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20308 →

Comments

Comment #0 by qs.il.paperinik — 2023-07-04T12:35:34Z
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.
Comment #1 by robert.schadek — 2024-12-13T19:30:01Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20308 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB