Bug 19587 – std.range.generate's range calls its argument one time too many

Status
NEW
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-01-15T21:59:11Z
Last change time
2024-12-01T16:34:47Z
Keywords
pull
Assigned to
No Owner
Creator
Paul Backus
Moved to GitHub: phobos#10366 →

Comments

Comment #0 by snarwin+bugzilla — 2019-01-15T21:59:11Z
Example: --- int count = 0; int counter() { return count++; } void main() { import std.algorithm; import std.range; import std.stdio; auto gen = generate!counter; gen.take(3).each!writeln; assert(count == 3); // fails, count == 4 } --- This behavior leads to two related problems: 1) Ranges, in general, are expected to be lazy. Eagerly calling the generator function on construction and in popFront violates that expectation. 2) As a result, writing optimal code using ranges created with `generate` (that is, code which does no unnecessary work) requires special-case handling, since Phobos' algorithms (for example, `take`, above) "naively" assume that construction and popFront are cheap. These problems are especially bothersome when the generator function is expensive to call (for example, if it accesses the network).
Comment #1 by dkorpel — 2021-05-06T22:53:27Z
Just got hit by this today, my `generate!(() => readln()).take(10).array` discarded the line after the 10 lines put into the array. This is really annoying, but changing this would be a breaking change, so I'm afraid the fix would be either: - a template parameter 'caching' with default value of `true` - a new synonym symbol, similar to `approxEqual => isClose`, with the possibility to deprecate the old symbol (caching can still be achieved by doing `generate!(f).cache`). I'm not sure what that synonym would be, things that come to mind are `generateLazy`, `successiveCalls`, `repeatEvaluate`, but I'm not a big fan of them.
Comment #2 by remi.thebault — 2022-05-06T16:50:40Z
*** Issue 23094 has been marked as a duplicate of this issue. ***
Comment #3 by dlang-bot — 2022-05-06T17:37:06Z
@rtbo created dlang/phobos pull request #8453 "fix issue 19587" fixing this issue: - fix issue 19587 avoid that std.range.generate calls fun one time too many https://github.com/dlang/phobos/pull/8453
Comment #4 by robert.schadek — 2024-12-01T16:34:47Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10366 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB