Sequences are a common example.
So this:
xs.map(x => x * 2).filter(x => x > 4).sorted().take(5)
In pipes this might look like: xs |> map(x => x * 2) |> filter(x => x > 4) |> sorted() |> take(5)
In functional languages (of the ML variety), convention is to put each operation on its own line: xs
|> map(x => x * 2)
|> filter(x => x > 4)
|> sorted()
|> take(5)
Note this makes for really nice diffs with the standard Git diff tool!But why is this better?
Well, suppose the operation you want is not implemented as a method on `xs`. For a long time JavaScript did not offer `flatMap` on arrays.
You'll need to add it somehow, such as on the prototype (nasty) or by wrapping `xs` in another type (overhead, verbose).
With the pipe operator, each operation is just a plain-ol function.
This:
xs |> f
Is syntactic sugar for: f(xs)
This allows us to "extend" `xs` in a manner that can be compiled with zero run-time overhead.e.g.
So this:
take(sorted(filter(map(xs, x => x \* 2), x => x > 4)), 5)
To your example: xs |> map(x => x \* 2) |> filter(x => x > 4) |> sorted() |> take(5)
is a marked improvement to me. Much easier to read the order of operations and which args belong to which call. xs
|> map(%, x => x * 2)
|> filter(%, x => x > 4)
|> sorted(%)
|> take(%, 5);
Anything that can currently just chain functions seems like a terrible example because this is perfectly fine: xs.map(x => x * 2)
.filter(x => x > 4)
.sorted()
.take(5)
Not just fine but much better. No new operators required and less verbose. Just strictly better. This ignores the fact that sorted and take are not actually array methods, but there are equivalent.But besides that, I think the better steelman would use methods that dont already exist on the prototype. You can still make it work by adding it to the prototype but... meh. Not that I even liket he proposal in that case.
> You can still make it work by adding it to the prototype
This is exactly what we want to avoid!
Why would you want to avoid that? It's controversial syntactic sugar. Enforcing a convention locally seems ideal.
2. There is a run-time overhead to wrapping
IMO a design goal of programming langauges should be for the most readable code to also be the most performant.
Language features tend to be controversial until they are mainstream.