January 15, 2019 [Issue 19587] New: std.range.generate's range calls its argument one time too many | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=19587 Issue ID: 19587 Summary: std.range.generate's range calls its argument one time too many Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: phobos Assignee: nobody@puremagic.com Reporter: snarwin+bugzilla@gmail.com 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). -- |
Copyright © 1999-2021 by the D Language Foundation