On Sunday, 2 June 2013 at 13:07:18 UTC, Andrei Alexandrescu wrote:
On 6/2/13 1:58 AM, Meta wrote:
For reference type ranges and input ranges which are not forward
ranges, this
will consume the range and return nothing.

I originally wrote it to accept forward ranges and use save, but I wanted to make it as inclusive as possible. I guess I overlooked the
case of ref ranges.
[snip]

Thanks for sharing your ideas.

I think consuming all of a range evaluating front and doing nothing should be the role of reduce with only one parameter (the range). That overload would take the range to be "exhausted" and return void. Thus your example becomes:

[1, 2, 3, 4].map!(n => n.writeln).reduce;


Andrei

One of the problems with using "map" for something such as this, is that the resulting object is not a range, since "front" now returns void, and a range *must* return a value. So that code will never compile (since reduce will ask for at least input range). Heck, I think we should make it so that map refuses to compile with an operator that returns void. It doesn't make much sense as-is.

Usage has to be something like:

map!((n) {n.writeln; return n;})

which is quite clunky. The idea of a "tee" range, that takes n, runs an operation on it, and then returns said n as is becomes really very useful (and more idiomatic). [1, 2, 3, 4].tee!(n => n.writeln). There! perfect :)

I've dabbled in implementing such a function, but there are conceptual problems: If the user calls "front" twice in a row, then should "fun" be called twice? If user popsFront without calling front, should "fun" be called at all?

Should it keep track of calls, to guarantee 1, and only 1, call on each element?

I'm not sure there is a correct answer to that, which is one of the reasons I haven't actually submitted anything.

--------

I don't think "argument-less reduce" should do what you describe, as it would be a bit confusing what the function does. 1-names; 1-operation, IMO. Users might accidentally think they are getting an additive reduction :(

I think a function called "walk", in line with "walkLength", would be much more appropriate, and make more sense to boot!

But we run into the same problem... Should "walk" call front between each element? Both answers are correct, IMO.

Reply via email to