February 28, 2013
On 2/28/13 3:03 AM, Jacob Carlborg wrote:
> On 2013-02-27 22:59, Andrei Alexandrescu wrote:
>
>> I like Tap (including the name). It is similar to Unix's "tee" utility.
>
> Cool, is this something that could be included in Phobos? If yes, where?

I think it belongs to std.range.

1. tap!fun(r) returns a new range (of a new type R1 distinct from typeof(r)). Upon the first call to .front without an intervening popFront, fun(r.front) is called.

2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described above, and fun2 whenever popFront() gets called without the front() being looked at. So fun1 tracks the looked-at data and fun2 tracks the ignored data.


Andrei
February 28, 2013
On 2013-02-28 16:18, Andrei Alexandrescu wrote:

> I think it belongs to std.range.
>
> 1. tap!fun(r) returns a new range (of a new type R1 distinct from
> typeof(r)). Upon the first call to .front without an intervening
> popFront, fun(r.front) is called.
>
> 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described
> above, and fun2 whenever popFront() gets called without the front()
> being looked at. So fun1 tracks the looked-at data and fun2 tracks the
> ignored data.

That is not my idea of "tap". This is my idea of "tap":

Object (func) (Object o)
{
    func(o);
    return o;
}

-- 
/Jacob Carlborg
February 28, 2013
On 2/28/13 10:24 AM, Jacob Carlborg wrote:
> On 2013-02-28 16:18, Andrei Alexandrescu wrote:
>
>> I think it belongs to std.range.
>>
>> 1. tap!fun(r) returns a new range (of a new type R1 distinct from
>> typeof(r)). Upon the first call to .front without an intervening
>> popFront, fun(r.front) is called.
>>
>> 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described
>> above, and fun2 whenever popFront() gets called without the front()
>> being looked at. So fun1 tracks the looked-at data and fun2 tracks the
>> ignored data.
>
> That is not my idea of "tap". This is my idea of "tap":
>
> Object (func) (Object o)
> {
> func(o);
> return o;
> }

I know. I think my tap is better than your tap.

Andrei


February 28, 2013
On 2/28/13 10:49 AM, Andrei Alexandrescu wrote:
> On 2/28/13 10:24 AM, Jacob Carlborg wrote:
>> On 2013-02-28 16:18, Andrei Alexandrescu wrote:
>>
>>> I think it belongs to std.range.
>>>
>>> 1. tap!fun(r) returns a new range (of a new type R1 distinct from
>>> typeof(r)). Upon the first call to .front without an intervening
>>> popFront, fun(r.front) is called.
>>>
>>> 2. tap!(fun1, fun2)(r) also returns a new range, calls fun1 as described
>>> above, and fun2 whenever popFront() gets called without the front()
>>> being looked at. So fun1 tracks the looked-at data and fun2 tracks the
>>> ignored data.
>>
>> That is not my idea of "tap". This is my idea of "tap":
>>
>> Object (func) (Object o)
>> {
>> func(o);
>> return o;
>> }
>
> I know. I think my tap is better than your tap.

... and closer in intent to Ruby's tap as I understand it from reading http://ruby-doc.org/core-2.0/Object.html#method-i-tap

No?

Andrei
February 28, 2013
On Thursday, 28 February 2013 at 15:51:02 UTC, Andrei
Alexandrescu wrote:
> On 2/28/13 10:49 AM, Andrei Alexandrescu wrote:
>> On 2/28/13 10:24 AM, Jacob Carlborg wrote:
>>> That is not my idea of "tap". This is my idea of "tap":
>>>
>>> Object (func) (Object o)
>>> {
>>> func(o);
>>> return o;
>>> }
>>
>> I know. I think my tap is better than your tap.
>
> ... and closer in intent to Ruby's tap as I understand it from reading http://ruby-doc.org/core-2.0/Object.html#method-i-tap

Ruby's tap just applies the passed block to the object it is
called on. I am not quite sure how your range idea comes into
play here?

David
February 28, 2013
On 2/28/13 11:36 AM, David Nadlinger wrote:
> On Thursday, 28 February 2013 at 15:51:02 UTC, Andrei
> Alexandrescu wrote:
>> On 2/28/13 10:49 AM, Andrei Alexandrescu wrote:
>>> On 2/28/13 10:24 AM, Jacob Carlborg wrote:
>>>> That is not my idea of "tap". This is my idea of "tap":
>>>>
>>>> Object (func) (Object o)
>>>> {
>>>> func(o);
>>>> return o;
>>>> }
>>>
>>> I know. I think my tap is better than your tap.
>>
>> ... and closer in intent to Ruby's tap as I understand it from reading
>> http://ruby-doc.org/core-2.0/Object.html#method-i-tap
>
> Ruby's tap just applies the passed block to the object it is
> called on. I am not quite sure how your range idea comes into
> play here?
>
> David

Oh, I misunderstood the example at http://ruby-doc.org/core-2.0/Object.html#method-i-tap:

(1..10)                .tap {|x| puts "original: #{x.inspect}"}
  .to_a                .tap {|x| puts "array: #{x.inspect}"}
  .select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"}
  .map { |x| x*x }     .tap {|x| puts "squares: #{x.inspect}"}

It eagerly prints the entire range, then eagerly prints the entire array, then eagerly the entire filtered range, then eagerly the entire map result.

I thought it works lazily, and I think in D it should (otherwise it would be e.g. useless with an input range). So the D translation would be:

iota(1, 10)
  .tap!(a => writeln("original: ", a))
  .filter!(a => a % 2 == 0)
  .tap!(a => writeln("filtered: ", a))
  .map!(a => a * a)
  .tap!(a => writeln("squared: ", a));

This will produce output interleaved, so it's semantically different.

I've used something similar to "tap" in a streaming-based library for machine learning I worked on as a grad student. It's been instrumental for data analysis and debugging. This conversation reminded me of it.

So my thought on the subject - I don't care much for

T tap(alias func)(T x) { func(x); return x; }

It's the kind of chaff that doesn't do any real work and only dilutes the value of a library, but I do think a tap tapping into a range does real work and would be a valuable addition.


Andrei
February 28, 2013
On 2013-02-28 18:08, Andrei Alexandrescu wrote:

> T tap(alias func)(T x) { func(x); return x; }
>
> It's the kind of chaff that doesn't do any real work and only dilutes
> the value of a library, but I do think a tap tapping into a range does
> real work and would be a valuable addition.

What about a function allowing both?

-- 
/Jacob Carlborg
March 02, 2013
"Ary Borenszweig" <ary@esperanto.org.ar> wrote in message news:512E717B.7090808@esperanto.org.ar...
>
> Then why not remove the binary "-" from D. You can always do:
>
> a + -b
>
> I believe this makes the language simpler.

Compatibility with C.


March 02, 2013
On 02/28/2013 06:08 PM, Andrei Alexandrescu wrote:
> ...
>
> So my thought on the subject - I don't care much for
>
> T tap(alias func)(T x) { func(x); return x; }
>

I'm not sure who would.

template tap(alias func){ T tap(T)(T x){ func(x); return x; } }

> It's the kind of chaff that doesn't do any real work and only dilutes
> the value of a library,  but I do think a tap tapping into a range does
> real work  and would be a valuable addition.
>...

map!(tap!func)
1 2
Next ›   Last »