std.range.cacheFront proposal&working code: wraps a range to enforce front is called only once

Jonathan M Davis jmdavisProg at gmx.com
Thu Oct 24 12:50:28 PDT 2013


On Thursday, October 24, 2013 12:14:27 Timothee Cour wrote:
> so far you've emphasized on the fact popFront should take care of all side
> effects and front should be logically pure and fast to compute, but you
> haven't suggested any alternative for what I'm trying to achieve.
> 
> In what I propose it's generic (works in all cases) and simple (just add
> ".cacheFront" after a lambda with side effect):
> 
> auto test(T)(T elements) if(isInputRange!T){
> return elements
> .map!( (a) {preaction(a); auto b=transform(a); postaction(a,b); return b;})
> .cacheFront
> .filter!foo; //or joiner or....
> }
> 
> So, how do you achieve the above without using cacheFront, without creating
> a _custom_ range or writing a lot of code ?
> I don't see how using foreach is a good idea (ForEachType!=ElementType, it
> doesn't reuse phobos functionality and doesn't play well with phobos range
> functions)

If you don't want to do this with foreach, then creating a custom range is 
exactly what you should be doing, and the logic for the pre and post 
operations should go in popFront. Having side effects in front is just begging 
for problems, and it's not at all what map is designed for. And honestly, if 
your popFront isn't pure as well, and the side effects that you're doing affect 
something outside of the range, then I would suggest that you not use ranges 
for what you're doing, because that violates their functional nature. You can 
do it if you want to, but that's not at all what they're designed for.

It has been proposed before that a function be added to Phobos which did an 
operation when iterating over an element, in which case that operation would 
go in popFront, and front would just return the wrapped front. That would 
probably get you what you want and be more generally applicable than 
cacheFront.

- Jonathan M Davis


More information about the Digitalmars-d mailing list