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

Reply via email to