wforney / morelinq

Automatically exported from code.google.com/p/morelinq
Apache License 2.0
0 stars 0 forks source link

Rename Pipe to ViaAction/Cause/Visit #10

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The Pipe operator sounds too general and vague. Any set of LINQ operations
chained together could be seen as a pipeline or pipe formation/composition.
Pipe also does not imply any side effect. Consequently, consider renaming
Pipe to ViaAction. ViaAction clearly states two things: (1) the operator is
pass-through, as in via, and (2) it implies an action, which for the
majority case is understood to be a side-effect.

Original issue reported on code.google.com by azizatif on 17 Feb 2009 at 9:05

GoogleCodeExporter commented 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:

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
> 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
> `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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
'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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
@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

GoogleCodeExporter commented 9 years ago
@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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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