In general, who should do more work: popFront or front?

surlymoor surlymoor at cock.li
Tue Jun 15 04:59:17 UTC 2021


On Tuesday, 15 June 2021 at 04:43:38 UTC, jfondren wrote:
> Well, consider this program:
>
> ```d
> import std;
>
> struct Noisy {
>     int[] source;
>     int pops, fronts;
>     bool empty() { return source.empty; }
>     void popFront() { writeln("popFront #", ++pops); 
> source.popFront; }
>     int front() { writeln("front #", ++fronts); return 
> source.front; }
> }
>
> void main() {
>     iota(5).array
>         .Noisy
>         .filter!"a%2"
>         .each!writeln;
> }
> ```
>
> Out of [0,1,2,3,4], only 1,3 pass the filter.
> Noisy's front is called seven times, 2x for each filter success.
> Noisy's popFront is called five times, 1x for each source 
> member.
>
> But if you slap a .cache (from std.algorithm.cache) before the
> .filter then these counts are the same.

Appreciate the response.
 From your example, one solution is that perhaps documenting one's 
custom range type with a disclaimer that its front method is 
expensive upon invocation is reasonable; the consumer of the 
range type, given this information, might then determine whether 
using cache is appropriate for them.
I'm still left wondering whether one should strive for ensuring 
that front is O(1), and various solutions to this. With that 
said, I now realize my question is kind of ridiculous since the 
answer might be predicated upon other aspects: the type data 
being consumed; the common operations that are to be performed 
upon a custom range.


More information about the Digitalmars-d-learn mailing list