5 ms·
How is the pipeline operator better than bog standard method chaining you have in any OO language? let result = "hello" |> doubleSay |> capitalize
by copx 9y ago
How is the pipeline operator better than bog standard method chaining you have in any OO language?
let result = "hello"
|> doubleSay
|> capitalize
|> exclaim;
vs.
result = "hello".doubleSay().capitalize().exclaim()
I certainly prefer method chaining here.
- boomlinde 9y agoIt makes more sense when not every function can be assumed to be a method, or when the processing chain involves more than one object.
- ramchip 9y agoIt works with functions rather than methods. So you can do something like this, calling functions from various modules / services: order = %{amount: 123, customer_id: 45} result = order |> Orders.validate() |> Database.save() |> PubSub.publish() whereas with method chaining you can only call methods of the object being passed around.
- bontaq 9y agoI think it's something more like making this better, not necessarily replacing method chaining. result = exclaim(capitalize(doubleSay("hello"))) and the pipe makes it simpler to read, especially if you're chaining some functions that can take additional arguments let result = "hello" |> sayTimes(3) |> capitalize |> exclaim
- fasquoika 9y agoThey basically serve the same function, however since many functional languages don't have method chaining they use the pipe operator instead. I honestly don't know why anyone would have a strong preference for one form over the other
- marcosdumay 9y ago- It's more extensible: You can defines functions over standard data types anywhere, you can't define methods for standard data types anywhere, - It's more flexible on input types: You can deal with sum types without polluting your classes with flags. - It's more flexible on execution order: You can shortcut things, you can define your operator in a way that it runs some things twice, you can jump over some function (if the typing allows). - It's more composable: You can intercalate this with other operators. - It's data: You can input the sequence into a function, rewrite it and execute the new sequence, interpret it and create some documentation, run some offline verification without executing the code, etc.
- bunderbunder 9y agoIt's not a replacement for method chaining, and can't even be used for that purpose. It's for rearranging the relative position of a function's arguments. In pseudocode, it's defined like: x |> f ->. f(x) So, applying that, it would let you transform something like exclaim(capitalize(doubleSay("hello"))) to your first example. But it can't do anything with the 2nd example, because those are not functions with arguments, they're all 0-arity method calls. More generally, I don't think this operator makes much sense in a language that's mostly object-oriented. I made one in Scala a while back and toyed with it, but even there it's pretty useless because the libraries follow a very object-oriented coding style. I've really only seen it shine in a language that has strong ML roots and tends to stick to them.
- tom_mellior 9y ago> those are not functions with arguments, they're all 0-arity method calls In other words, they are 1-argument function calls. The "this"/"self" parameter is implicit in many languages, but otherwise it's not different from a normal function parameter. In the "method chaining" version of the example, each method call returns a (reference to) a temporary object which is passed as the next method call's "this" parameter.
- bunderbunder 9y agoIn most languages, that's an implementation detail that is hidden by the compiler, and not a part of the semantics of the language itself. More specifically, if the language won't allow me to do both: foo.method(x) and method(foo, x) and have them behave the same way, then I submit that, regardless of what's going on behind the curtain, a n-arity method is not really the same thing as a (n+1)-arity function in that language.
- kd5bjo 9y agoPython is pretty close to this. Assuming that foo is an instance of class Bar, foo.method(x) Is equivalent[1] to Bar.method(foo, x) [1] in the absence of monkey patching on foo