March 21, 2014
On Friday, 21 March 2014 at 00:42:00 UTC, Walter Bright wrote:

> Right on.

I'm using Ruby every day. I don't really see much point in having "each" in D. We already have "foreach". Ruby uses "each" since it doesn't have "foreach". It to have a "for", which is a form of foreach, but that is just lowered to "each" anyway.

Also, I don't see a point in having "each" which is lazy.

--
/Jacob Carlborg
March 21, 2014
On Friday, 21 March 2014 at 11:03:01 UTC, monarch_dodra wrote:

> each "tee" triggers on the call to `popFront`. It does its job (calls pred(r.front)), and then push the "pop down the chain. What this means is that my "tee's" are actually executed right to left! Talk about counter intuitive.

What's the purpose of "tee", is it the same as "tap"? "tap" in Ruby just returns the receiver after executing a block. This would be the implementation in D:

T tap (alias block, T) (T t)
{
    block(t);
    return t;
}

--
/Jacob Carlborg
March 21, 2014
On Friday, 21 March 2014 at 12:55:09 UTC, Jacob Carlborg wrote:
> What's the purpose of "tee", is it the same as "tap"? "tap" in Ruby just returns the receiver after executing a block. This would be the implementation in D:

Yeah "tee" is a horrible name, no chance I would have guess what it means just by the name. "tap" is much better.
March 21, 2014
On Friday, 21 March 2014 at 13:24:50 UTC, Dicebot wrote:
> On Friday, 21 March 2014 at 12:55:09 UTC, Jacob Carlborg wrote:
>> What's the purpose of "tee", is it the same as "tap"? "tap" in Ruby just returns the receiver after executing a block. This would be the implementation in D:
>
> Yeah "tee" is a horrible name, no chance I would have guess what it means just by the name. "tap" is much better.

I think it's meant to mimic the UNIX command with the same name? If you know about the command, the function's purpose seems obvious.
March 21, 2014
Vladimir Panteleev:

> Dicebot:
>> Yeah "tee" is a horrible name, no chance I would have guess what it means just by the name. "tap" is much better.
>
> I think it's meant to mimic the UNIX command with the same name? If you know about the command, the function's purpose seems obvious.

See also the Python function tee():
http://docs.python.org/2/library/itertools.html#itertools.tee

Bye,
bearophile
March 21, 2014
On Friday, 21 March 2014 at 13:27:04 UTC, Vladimir Panteleev wrote:
> On Friday, 21 March 2014 at 13:24:50 UTC, Dicebot wrote:
>> On Friday, 21 March 2014 at 12:55:09 UTC, Jacob Carlborg wrote:
>>> What's the purpose of "tee", is it the same as "tap"? "tap" in Ruby just returns the receiver after executing a block. This would be the implementation in D:
>>
>> Yeah "tee" is a horrible name, no chance I would have guess what it means just by the name. "tap" is much better.
>
> I think it's meant to mimic the UNIX command with the same name? If you know about the command, the function's purpose seems obvious.

...and has pretty much nothing in common with it! Also I don't see "requires UNIX familiarity to be used intuitively" warning in Phobos docs. Actually for similar reasons "tap" is also inferior to "each".
March 21, 2014
On 3/21/14, 4:02 AM, monarch_dodra wrote:
> So I toyed around a little. I played with mostly tee/tap and each. The
> first observation is that both can help make a "2D" ufcs chain, which is
> pretty nice. It makes more sense (IMO) to code it that way, than to use
> awkward "join", to concatenate the "2D" range into a continuous "1D"
> range, eg: join(lines, "\n");
>
> First: "tee".

Nice work! This convinced me that tee should call the lambda only upon the first call to .front on each iteration.

Andrei


March 21, 2014
On Friday, 21 March 2014 at 12:29:31 UTC, bearophile wrote:
> So before taking any decision on the matter, more experiments and usage examples are necessary, where you have longer chains. If you have a longer chain:
>
> items
> .sort()
> .group
> .map!(g => g[1] / double(s.length))
> .map!(p => -p * p.log2)
> .sum
> .each(...);
>
> using a each() allows you to keep a nice column. If you use foreach your formatting and your logic has a hiccup, because you are mixing two different styles:
>
> foreach (item; items
>                .sort()
>                .group
>                .map!(g => g[1] / double(s.length))
>                .map!(p => -p * p.log2)
>                .sum) {
>     // Do something imperative here.
> }
>
> But this is not a real example (it computes the entropy of items, and you usually don't need an each there), so more usage examples are needed. Taking a look at real world usages of foreach() in Scala could be useful.

The former example doesn't become functional just because you managed to use UFCS, it's just imperative code deceptively disguised as functional code. The clear separation in the latter example is a *good thing*.

March 21, 2014
On Friday, 21 March 2014 at 11:03:01 UTC, monarch_dodra wrote:
> //----
> foreach ( a ;
>     chain(iota(0, N), only(N), iota(0, N).retro) )
> {
>     writeln(' '.repeat(N - a), '*'.repeat(a*2+1)))
> }
> //----

I don't think it's so complicated. It's just taking this.

someRange.mungeItHowever.each!useIt;

Instead of writing this.

foreach(someThing; someRange.mungeItHowever) someThing.useIt;

Maybe it's like the difference between writing foo(bar) and bar.foo. It can just look a little nicer.
March 23, 2014
On Thursday, 20 March 2014 at 15:25:47 UTC, Andrea Fontana wrote:
> Why isn't ParallelForEach implemented as Range, instead?

Because it can't be. It's not possible to present something as a range, so that that range's consumers would process that range in parallel. std.parallelism.parallel instead (ab)uses the opApply implementation mechanics to execute the foreach body in different threads.