Open GoogleCodeExporter opened 9 years ago
Should you choose to accept, a patch is attached to make this painless. :)
Original comment by azizatif
on 17 Feb 2009 at 9:09
Attachments:
I think Pipe is ok. The purpose of a pipe is to pass something through to what
comes
after, so I think it is just as expressive as "via". It's not perfect, as it
evokes
the Unix idea of a "pipeline", which is technically very similar to what most
of the
LINQ operators already do: allow function chaining.
But if we are going to consider alternatives, I'm fond of "Visit", because it
evokes
the Visitor Pattern: http://en.wikipedia.org/wiki/Visitor_pattern
Original comment by CAmmerman@gmail.com
on 17 Feb 2009 at 9:14
The Unix idea of a pipeline is exactly what I was thinking of, but I'm not
convinced
by any of the names suggested so far. Keep thinking, everyone :)
Original comment by jonathan.skeet
on 17 Feb 2009 at 9:27
How about Cause? Cause implies action and effect. It also reads nice:
"foo bar".Split().Cause(Console.WriteLine).Consume();
Original comment by azizatif
on 17 Feb 2009 at 10:28
At a glance I would expect "Cause" to be synonymous to "ForEach". I think it's
crucial that the pass-through behavior of this method be reflected in the name.
Original comment by CAmmerman@gmail.com
on 17 Feb 2009 at 10:34
ForEach is well-understood to be a terminal. There should no confusion in
anyone's
mind what ForEach does otherwise it means we have introduced an element of
surprise.
I agree, though, that Cause may not imply continuation but we should strive to
have
only two terminals: ForEach and Exhaust/Consume. This way, we can be relaxed
about
how many behaviors does a single word embody. And come to think of it, ForEach
is
Cause followed by Exhaust/Consume. ;)
I've updated the issue summary to reflect the current options.
Original comment by azizatif
on 17 Feb 2009 at 11:21
Speaking of Exhaust, should we have that as a "normal" method? I've currently
just
got it as a test helper, but it might not be a bad thing to include for
completeness.
Another option: "Observe" - I get to take an action when I see something, but
not
interfere with the fact that it's being passed along the pipe.
Original comment by jonathan.skeet
on 17 Feb 2009 at 11:25
> Speaking of Exhaust, should we have that as a "normal" method?
Yep, posted as Issue #11.
Original comment by azizatif
on 17 Feb 2009 at 11:43
Observe sounds interesting until you consider the "action" part. If you
consider the
signature in pseudo code, it reads odd:
Observe(source, action)
Likewise, it just doesn't read right when put in usage:
"foo bar".Split().Observe(Console.WriteLine).Consume();
Although you could say the Console is "observing" each string as it passes
through,
the WriteLine bit disturbs or feels extra. It has a whole different feel when
you
change Observe to Notify and use Console like this:
"foo bar".Split().Notify(Console).Consume();
This reads natural and implies an imperative action but it doesn't get us
anywhere.
Original comment by azizatif
on 17 Feb 2009 at 11:57
Why not call it `Tee` in reminiscence of the [UNIX command][1] that IMHO most
closely
fits this action? May be too obscure though. An alternative might be `Fork`
although
this somehow seems to imply that two enumerables are returned.
[1]: http://en.wikipedia.org/wiki/Tee_(command)
Original comment by konrad.r...@gmail.com
on 18 Feb 2009 at 9:39
I did wonder about Tee. That's more likely to be reasonable in Push LINQ
though,
where it may mean something slightly different (if it actually turns out to be
needed; multicast events probably make it pointless).
Keep the ideas coming though... I'm going to blog on the difficulty of naming
quite
soon.
Original comment by jonathan.skeet
on 18 Feb 2009 at 9:44
> `Fork` although
> this somehow seems to imply that two enumerables are returned.
And adding to the frustration, Python does with Tee what you mean here with
Fork:
http://docs.python.org/3.0/library/itertools.html#itertools.tee
For someone who works in both camps, it can be frustrating to have one tee
causing
side-effects while the other not.
I would reserve Fork for parallelism and Tee for how Python does it. It would
be a
shame to loose both names to side-effects when they don't necessarily have to
imply it.
Original comment by azizatif
on 18 Feb 2009 at 10:05
Any judgment/criticism/etc. of my "Visit" suggestion? Another possibility may
be
"Apply", as in "apply this method to each element".
Original comment by CAmmerman@gmail.com
on 19 Feb 2009 at 4:05
Would Process not be a valid name for Pipe? It implies that a transformation
occurs
and that there is an output.
Original comment by jeffma...@gmail.com
on 10 Mar 2009 at 9:54
'Scuse me for butting in out of the blue, but how about just SideEffect instead
of
Pipe, because that is clearly what it is made for. In this sense, Trace is just
a
special case of SideEffect.
I wouldn't have categorised ForEach as SideEffects, because it implicitly
consumes
the IEnumerable, which is hardly a side effect, in my book.
Original comment by ben.simk...@gmail.com
on 25 Mar 2009 at 11:40
PS (and afterwards I'll shut up), Pipe looks like this to me (nothing to do
with Linq):
//pipe an action or function behind a function result
public static void Pipe<T>(this T val, Action<T> action) where T : class
{
if (val != null) action(val);
}
public static R Pipe<T, R>(this T val, Func<T, R> func)
where T : class
where R : class
{
return val != null ? func(val) : null;
}
(CF: http://stackoverflow.com/questions/336775/pipe-forwards-in-c)
Original comment by ben.simk...@gmail.com
on 26 Mar 2009 at 6:37
I think "ForEach" would have been good, and its side effect behavior would be
consistent with ToList().ForEach(). But then the name would not imply that it
returns the transform, which List<T>.ForEach() does not. Confusion ensues.
I worry slightly about the user experience here. Nowhere else in the LINQ space
is the concept of lazy evaluation explicit. I don't think the majority of LINQ
users knows about it. Therefore, terms like ForceSelect, or likewise, will
confuse people.
I don't like "Pipe" really, speaking from process automation, because a pipe is
a passive thing. You PUT one thing in one end and this causes something to come
out the other end. In that regard, maybe it should be PUMP, but then it feels
like we're losing connection with out math/academic roots. Losing our monads,
so to speak.
Original comment by tormod.s...@gmail.com
on 16 Jun 2012 at 11:56
I'd be really worried about any MoreLINQ users who didn't understand lazy
evaluation already, to be honest.
How about we make it really, really explicit what this operator is for?
"WithSideEffect":
var query = input.Where(...).WithSideEffect(Console.WriteLine);
The "With" suggests it's still returning something, and it's clear that the
purpose is to add a side-effect to the pipeline.
Original comment by jonathan.skeet
on 16 Jun 2012 at 4:50
The eager execution nature of the operator, which is the motivation behind it,
would still not be explicit. "Select" also has side effects.
I may be (very) colored from my work in process automation industry, but
ideally it should be something suggesting that it is an active element (actor)
in the pipeline. WithSideEffects suggests that something extra (side effects)
happens when stuff is pulled through it.
Original comment by tormod.s...@gmail.com
on 17 Jun 2012 at 9:12
Perhaps we can settle on this one with Do as Interactive Extensions (Ix) does?
FWIW, at least it will provide some consistency (at the risk of issue #60
expanding for projects using MoreLinq and Ix).
Original comment by azizatif
on 17 Jun 2012 at 9:53
@tormod: The Pipe operator *doesn't* execute eagerly. It *is* lazy - the
motivation isn't to make it execute eagerly, it's to add a side-effect. Your
statement of:
"WithSideEffects suggests that something extra (side effects) happens when
stuff is pulled through it."
... is exactly correct. That's what the operator does. Look at the
implementation!
Original comment by jonathan.skeet
on 17 Jun 2012 at 11:19
@azizatif: I would suggest that projects using both MoreLINQ and Ix are going
to have a lot of duplication already. Personally I wouldn't want to use the two
together - I expect it would cause more harm than good.
"Do" feels very woolly to me, and suggests more eagerness. I'm still keen on
WithSideEffects - especially as Tormod understood exactly what that meant *even
though he expected something else*. That suggests it's a good name, IMO :)
Original comment by jonathan.skeet
on 17 Jun 2012 at 11:21
Oh, I am sorry. I have now looked at the code and I agree that "Do" seems to be
the correct choice. I am not saying that this is necessarily what we would be
arriving at in this discussion, but this is certainly what people will be
looking for, and will immediately understand, after they have started to use Rx
(or Ix).
To answer my own question. The thing that sets it apart from Select is that it
accepts an action as argument and returns the element (not a transformation of
the element).
Original comment by tormod.s...@gmail.com
on 26 Jun 2012 at 10:34
Is this project still alive? If so, and feedback is still appreciated, can I
suggest something along the lines of OnEnumerate, WhenEnumerated, or if you
like it really verbose WhenEnumeratedPerform? IMO it makes it clear that this
is lazy (i.e. performed when it is enumerated) and the signature makes it clear
it is a side effect action, and is chainable.
Original comment by MartijnH...@gmail.com
on 18 Nov 2013 at 12:14
Original issue reported on code.google.com by
azizatif
on 17 Feb 2009 at 9:05