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