-
Notifications
You must be signed in to change notification settings - Fork 2k
Pipeline support #1339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
If you can edit this post to indent all code with four spaces, it'll make things easier to read. |
that was quick :), i figured i'd get my thoughts down, then pretty it up with whatever formatting options github had, which turned out to just be a dialect of markdown |
I think this would indeed be an immensely useful idiom. One way to think about it is as an analogue to the chaining one would get if each function were a method of the last function's result. But this is obviously much more flexible. If I'm not mistaken, clojure does a very similar thing via a built-in macro. |
If i implement this well in a fork, how likely would it be to be integrated back into coffeescript? |
Not likely -- see all of the previous "pipe" tickets. |
I realize the general consensus is against this, but I find the idea interesting and I wonder if you guys would be so kind as to humor me for a moment and pretend this was to be implemented. I'm curious as to your thoughts on the following possible syntax: The pipe operator |>, passes the result of the previous operation to the next one. By default, the previous result is passed in as the first argument:
possible compilation:
Binding pipe operator: <|, all following operations are bound to the context of the result of the expression preceding The default passing of the results is turned off.
possible compilation:
If the rebinding occurs in the middle of a piping, the context is rebound, but the results of the previous piping are passed on:
possible compilation:
#@ calls the function as a method of the current __context:
possible compilation:
Empty context just continues default pipe behaviour: new Foo <| #@makebig 10 |> <| addFooChild possible compilation:
Piping #@ simply puts __context in __result: new Foo <| #@makebig 10 |> #@ |> myBar <| #@addFooChild possible compilation:
Additionally/Alternatively, #@ could be used as an argument. Handling positional arguments; by default the result of the previous pipe is passed to the first argument, but this can be redirected with #
possible compilation:
Destructuring; the return value of the previous operation can be destructured with #:
possible compilation:
Or:
possible compilation:
So those are just some rough ideas I just had, not wholly fleshed out yet. Some of this syntax may be unnecessary, and some of the "defaults" might be switched around, but I hope you get the general idea. Also, I realize the examples aren't great either but I'm mainly concerned about the syntax. Not covered is assigning the results of the piping to something, but I think you can see how straight-forward that would be. My thought is that overall, chaining should be the go-to tool for this type of semantics, but chaining has some drawbacks. With chaining all the methods have to be a property of or mixed in to some master object, and the methods have to be written to take arguments in a certain way. This type of piping allows you to use arbitrary functions and I believe allows more control over the "flow". I think in certain situations it would be a nice tool to have. I could see some drawbacks in readability etc, but IMHO it's not too bad. It's getting away from the "it's just Javascript" philosophy a little bit, but the compiled code should be pretty straight-forward. |
Pretty much my thoughts, even though I'm not sure I'd be comfortable with all that extra syntax you're suggesting. I think the basic |
odf: Agreed. I think it would be nice to have such diverse options, but it is a lot of syntax to add/read. I think just simple piping + handling positional arguments + destructuring would provide enough benefit over chaining that it would be worth it to add. In addition to not being tied to "chainable" functions, a compiled pipeline would probably involve less run time overhead. |
The idea of I much prefer the coffeey, readable versions of this:
|
How about this? It's less "magical" (what @ricardobeat didn't like), but you have to write a little bit more.
compiles to something like
Maybe we could even combine both ways and just assume that Advantages:
|
@thejh I'd rather have your example compiled to
for clarity, performance and mantaining scope. But your proposal is quite reasonable considering the use of expressions. On the other hand, making the name A related discussion is happening in #1407, on chaining function calls. |
That could mess up evaluation order. Consider:
↓
where |
in the previous discussion on ticket 281 it was said that function chaining could do the same thing. This is not the case `````` get().head().sort()
|
+1 for F# style pipelining. This is one of my favorite idioms from F#. |
Folks, this isn't a full substitute for F#
As in:
|
i have played around with doing that sort of thing inline before, but *where = (list,func) -> item for item in list when (func.call _ :item) pipe = (listoflists...) -> results = pipe [getnums, 10] , [where, -> @_ > 5 ] ,[select , "pre","post" ]
|
@klumsy, or, using the above
I tend to prefer this |
you opened my mind to a whole nother world of possibilies with your -> -> Thanks. On Mon, Nov 21, 2011 at 4:12 PM, Alessandro Vernet <
|
A recent proposal to add method cascades to Dart would make it possible to write Dart code as follows:
In CoffeeScript, we can declare a
This allows us to write the above Dart code, in CoffeeScript, as:
(Posting this as a follow-up here, as the ressemblance between cascades and pipelines is striking.) |
I'd like to re-start a discussion on this. "Method cascades" are obviously shitty, because if user'll want to define new method, he'll be forced to change LiveScript has [1 2 3 4 5]
|> map (+ 5)
|> filter (> 6) As you see, |
@paulmillr the Anyway, I hope to see such construct. Functional languages opened my eyes in it's ability to compose functions. |
@OnesimusUnbound until then we can use |
I really like the @thejh's I'm also concerned with the @ricardobeat's point about a new keyword, but I don't like the @satyr's |
Just for my own sanity, would anyone be kind enough to explain what the difference is between the following two lines?
I fail to see what the later can do that the former can't?? The first way allows for more than one arg too.
The trick is ensuring that each function can be called with one argument which is of a kind that each of the functions will return, generally an object with one or more required properties. |
What the difference is between Javascript and Coffeescript? Javascript can do everything that Coffeescript do. So... forget... Lets be nice. :-) select (where (getnums 10) ,-> @_ > 5) , "pre", "post" getnum |> where -> @_ > 5 |> select "pre", "post" The second looks more "natural" to me. My 2¢. |
Thank God for Coco. If it didn't exist, I'd be forced to use half of it. |
@aurium The "duplicate of" issue was closed. |
@vendethiel so is this open?! |
I know that this has been written up before , and the current consensus is that 1) it has a limitation that it doesn't allow functions with multiple arguments, and that it is a niche functionality only useful for DSLs.. I think that 1) it doesn't have to have that limitation, and you can look at F#'s implementation to show this, and 2 it can be very generic and useful, as seen in both F# and more so in powershell.
here is a link to how it is done in F# http://lorgonblog.wordpress.com/2008/03/30/pipelining-in-f/
Here is some coffee of mine doing a scenario. first how i have to call it now, then how i'd like to be able to call it, and third how i can do it with a helper function, then following up with how it can be done in kaffiene currently. The example is rather contrived but it should be sufficient to communicate
is there any easier way i can write the following below
alert res for res in results
what it really would like to do is be able, whether using | or say |> for a pipe do
basically the pipe takes the output of the previous command and puts it as teh first argument, and then takes any other arguments after that (so 1st argument becomes 2nd, and second becomes third..
with my own pipe i can do something like
pipe getnum .to where, -> @_ > 5 .to select , "pre","post"
kaffiene though not complete lets me do this with
and call it like this in kaffiene
generates the following javascript
and
The text was updated successfully, but these errors were encountered: