Comments (26)
Should you choose to accept, a patch is attached to make this painless. :)
Reported by @atifaziz on 2009-02-17 21:09:39
- Attachment: ViaAction.patch
from morelinq.
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
Reported by @cammerman on 2009-02-17 21:14:08
from morelinq.
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 :)
Reported by @jskeet on 2009-02-17 21:27:45
from morelinq.
How about Cause
? Cause
implies action and effect. It also reads nice:
"foo bar".Split().Cause(Console.WriteLine).Consume();
Reported by @atifaziz on 2009-02-17 22:28:06
from morelinq.
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.
Reported by @cammerman on 2009-02-17 22:34:13
from morelinq.
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.
Reported by @atifaziz on 2009-02-17 23:21:47
from morelinq.
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.
Reported by @jskeet on 2009-02-17 23:25:47
from morelinq.
Speaking of Exhaust, should we have that as a "normal" method?
Yep, posted as Issue #11.
Reported by @atifaziz on 2009-02-17 23:43:36
from morelinq.
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.
Reported by @atifaziz on 2009-02-17 23:57:47
from morelinq.
Why not call it Tee
in reminiscence of the UNIX command 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.
Reported by konrad.rudolph
on 2009-02-18 09:39:49
from morelinq.
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.
Reported by @jskeet on 2009-02-18 09:44:35
from morelinq.
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.
Reported by @atifaziz on 2009-02-18 10:05:25
from morelinq.
Any judgment/criticism/etc. of my Visit
suggestion? Another possibility may be Apply
, as in "apply this method to each element".
Reported by @cammerman on 2009-02-19 16:05:41
from morelinq.
Would Process
not be a valid name for Pipe
? It implies that a transformation occurs and that there is an output.
Reported by jeffmagic
on 2009-03-10 21:54:45
from morelinq.
'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.
Reported by ben.simkins
on 2009-03-25 11:40:30
from morelinq.
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)
Reported by ben.simkins
on 2009-03-26 06:37:16
from morelinq.
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.
Reported by tormod.steinsholt
on 2012-06-16 11:56:54
from morelinq.
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.
Reported by @jskeet on 2012-06-16 16:50:02
from morelinq.
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.
Reported by tormod.steinsholt
on 2012-06-17 09:12:33
from morelinq.
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).
Reported by @atifaziz on 2012-06-17 09:53:49
from morelinq.
@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!
Reported by @jskeet on 2012-06-17 11:19:16
from morelinq.
@atifaziz: 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 :)
Reported by @jskeet on 2012-06-17 11:21:07
from morelinq.
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).
Reported by tormod.steinsholt
on 2012-06-26 10:34:32
from morelinq.
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.
Reported by MartijnHoekstra
on 2013-11-18 12:14:23
from morelinq.
What about DoYield
?
var avg = new[] {1, 2, 3}.DoYield(x => Console.WriteLine(x)).Average()
from morelinq.
@JamesFaix I think it would be reasonable/sensible at this stage to borrow Do
from Rx here and move on.
from morelinq.
Related Issues (20)
- FullGroupJoin with null keys HOT 1
- Suggestion: WithIndex<T> Extension Method to facilitate enumerating with an item and index tuple HOT 1
- Compile Error MoreLinq/ToDataTable.cs HOT 2
- Hide `ToDictionary()` in net8+
- Remove `Windowed` that's been obsolete since 3.0
- Add `Minima` & `Maxima` to supersede `MinBy` & `MaxBy`
- Hide `CountBy` in net9+
- Review NUnit1030
- Review NUnit1029
- `Pad` should throw `ArgumentOutOfRangeException` for invalid width
- `PadStart` should to throw `ArgumentOutOfRangeException` for invalid width
- `Interleave` shouldn't validate `otherSequences` members
- Improve GroupAdjacent HOT 9
- Remove tail items while condition is true
- Revise tests to avoid using `Eumerable.Range` HOT 4
- `Subsets` enumerator doesn't return same array from `Current`
- `Merge` masks original exception with an `ArgumentException` about no tasks
- Async versions of OrderedMerge and GroupAdjacent HOT 3
- `Rank` does not iterate source on re-iterations
- Installing MoreLINQ NuGet 4.2 "Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))" HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from morelinq.