8 ms·
Elixir (and some other languages as well) solves this with the pipe operator: some_array |> do_thing() |> do_another_thing() |> do_something_else() Even thoug
by jonnycat 5y ago
Elixir (and some other languages as well) solves this with the pipe operator:
some_array
|> do_thing()
|> do_another_thing()
|> do_something_else()
Even though Elixir is functional and aggressively not object oriented, if you squint at this pattern you get the readability of an OO-style method chaining API.
- amw-zero 5y agoNow replace |> with . And you have the previous code example. The difference is completely superficial.
- machiaweliczny 5y agoIt's not because you can use any function with pipeline and with dots chaining you can use only methods returned by previous function call.
- kazinator 5y agoThat is false; you cannot chain functions that do not return a value that is suitable as an argument to the next function. a.this().that() requires that a.this() returns an object on which .that() can be invoked. (that (this a)) requires that (this a) returns an object that is a suitable argument to that.
- jonnycat 5y agoThe end result is superficially different. That's the point - we like the flow of the end result! But the implementation is completely different, as it's pure functional compared to object oriented. "string".do_stuff() - do_stuff() is a method on the "string" class, with all of the potential gotchas that might come with an OO implementation. Does the method mutate the internal state of the object? Does the particular class override the default implementation? Is it a monkey-patched implementation (the issue raised by this article)? "string" |> do_stuff() - do_stuff() is a standalone pure function. The data is immutable and does exactly what it says.
- kazinator 5y agoNot completely, because the . has a meaning: select a member/field/slot from a class object.
- jon1628492 5y agoOr alternatively, some_array |> do_thing() |> do_another_thing() |> do_something_else()
- deleted 5y ago[deleted]
- omoikane 5y agoFeature request for pipeline operator in Ruby: https://bugs.ruby-lang.org/issues/15799 https://bugs.ruby-lang.org/issues/15799 See also: https://mamememo.blogspot.com/2019/06/a-brief-history-of-pipeline-operator.html https://mamememo.blogspot.com/2019/06/a-brief-history-of-pip... https://mametter.hatenablog.com/entry/2019/06/15/192311 https://mametter.hatenablog.com/entry/2019/06/15/192311
- leifg 5y agoIf I understand the Ruby pipeline operator it's essentially an alias of the dot. The example in the feature tracker is: ``` 1.. |> take 10 |> map {|e| e2} |> (x) ``` which is equivalent to ``` (1...).take(10).map{|e| e2} ``` So in order to use it you still need extensions on every single object. The only reason that looks nice is because in this example you continuously call methods on lists that return a list. You can't add `my_custom_list_operation(list_input)` in between.
- dragonwriter 5y agoIt's worth noting that that version of pipeline operator was abandoned, while there are still (some newer) open feature requests for a more traditional functional-style pipeline operator.
- tylerscott 5y agoyield_self is an less elegant way to achieve basically the same thing as |>.
- WallowingInShit 5y agoSame thing, but for JavaScript: https://github.com/tc39/proposal-pipeline-operator https://github.com/tc39/proposal-pipeline-operator Going forward, the pipe operator is going to be showing up in many new languages. I've used elixir a lot, and the pipe operator is a genius piece of syntactic sugar.