Feature #17353
openFunctional chaining operator
Description
Since ruby already moving in that direction(functional), I would like to propose add to it OCaml-like chaining/pipe operator into ruby.
Which would allow such syntax
def handle(requests) = requests
|> Array.filter { not _1.from.user.banned? }
|> Array.map { _1 |> main_router.emit }
|> Array.each &awaiter
What exactly happens here ?
Let's look at a bit easier example:
gets.to_i
|> make_stuff
|> format "the number is %d"
|> puts
Which is expands exactly to the code below
puts(format("the number is %d", make_stuff(gets.to_i)))
So what this operator does is nothing but just tricky form of AST building
Advantages:
- Increase readability
- It's more duck type-ish
Limitations:
- cant be overloaded
Updated by zverok (Victor Shepelev) about 4 years ago
"Let's take |>
from Elixir" is proposed roughly once a month. The problem with this proposal is that it doesn't work well with Ruby syntax. Ruby's core chaining module is Enumerable
("core" in the sense it shows how the things are designed here), and core chainable item is block.
So let's look at your example:
def handle(requests) = requests
|> Array.filter { not _1.from.user.banned? }
|> Array.map { _1 |> main_router.emit }
|> Array.each &awaiter
There is no way (besides "it is Elegant Because It Is Elegant In Elixir") how exactly it is better than
def handle(requests) = requests
.filter { not _1.from.user.banned? }
.map { main_router.emit(_1) }
.each &awaiter
Now, this (one-item chaining):
gets.to_i
|> make_stuff
|> format "the number is %d"
|> puts
is handled by Object#then, existing since 2.6:
gets.to_i
.then(&method(:make_stuff))
.then { format "the number is %d", _1 }
.then(&method(:puts))
Which is exactly "ideologically compatible" with how Enumerable chaining works, trivially implemented and place nice with all possible Ruby intuitions.
Now, method references and currying is another, sadder, story, but it would be sad with any chaining syntax.
Updated by matz (Yukihiro Matsumoto) about 4 years ago
- Related to Feature #15799: pipeline operator added
Updated by matz (Yukihiro Matsumoto) about 4 years ago
- Related to Feature #16794: Rightward operators added
Updated by nobu (Nobuyoshi Nakada) about 4 years ago
Off topic:
fulcanelly (Maks Kompanienko) wrote:
def handle(requests) = requests |> Array.filter { not _1.from.user.banned? } |> Array.map { _1 |> main_router.emit } |> Array.each &awaiter
This made me want to disable fluent-dots in endless-def...