emit: generalizes map, filter, joiner [proposal + implementation]

cy via Digitalmars-d digitalmars-d at puremagic.com
Fri Mar 25 01:35:09 PDT 2016


> template emit(T, alias fun)

I wonder if "template emit(alias fun, T)" wouldn't be a better 
idea. That way you could leave T open for type inference, even if 
you specify a function. D doesn't support reordering template 
arguments, so it's important to put the ones "most used" at the 
beginning.

Anyway, it looks neat. I hope you've looked at 
std.algorithm.iteration.reduce though? It does the same thing 
that emit does, and it's an ancient algorithm.

"fold" is just reduce with the arguments more convenient for D's 
syntax. But...


assert(9.iota.emit!(int,(put,a){if(a%2) put(a*a);}).equal([1, 9, 
25, 49]));
=>
int[] intderp;
assert(9.iota.fold!((result,a) { if(a%2) return result ~ [a*a]; 
else return result;})(intderp) == ([1,9,25,49]));

What would be neat is a "reduce" that could produce an infinite 
range as a result. All I can do with reduce and fold is produce 
an eagerly evaluated growing array in memory, or something like 
chain(chain(chain(chain(chain(...))))) which uses up memory just 
from creating all those iterators. Like, I don't know how to use 
fold! to do this:

   auto natural_numbers = sequence!"n"();
   auto oddsquared = natural_numbers.filter!"a%2==1".map!"a*a"; // 
fold?
   assert(take(oddsquared,4).equal([1, 9, 25, 49]));


More information about the Digitalmars-d mailing list