From: "AlexandreMagro (Alexandre Magro) via ruby-core" Date: 2024-10-02T16:14:45+00:00 Subject: [ruby-core:119408] [Ruby master Feature#20770] A *new* pipe operator proposal Issue #20770 has been updated by AlexandreMagro (Alexandre Magro). zverok (Victor Shepelev) wrote in #note-28: > What would `|>` bring here? > ```ruby > row > .split('|') > .map { parse(it) } > .filter(&:odd?) > |> MyModule.process_numbers(it) > .join('-') > ``` > In my view, only syntactical/semantic confusion (what���s the scope in `|>` line? is `join` attached to its result, or is it inside the ���invisible block���?.. Why do we have a fancy symbol for `.then`, but not for `map` or `filter`, which are arguably even more widespread?..) I���d like to turn the question around and ask what would be returned from the following code? ```ruby array_a = [{ name: 'A', points: 30 }, { name: 'B', points: 20 }, { name: 'C', points: 10 }] array_b = [{ name: 'D', points: 0 }, { name: 'E', points: 0 }] array_c = array_a .sort { |a, b| b[:points] <=> a[:points] } + array_b .map { |el| el[:name] } ``` This highlights that mixing operators and methods within a chain can indeed create confusion. The example is tricky because it's not clear if `+` is meant to apply to the results of array_a's sort or to the entire combination of array_a and the mapped values of array_b. In the same way, the `|>` operator might introduce confusion if it's mixed in with method chains without proper context. However, just like `+`, `|>` is simply another operator. It can be understood like: - `a |> b` translates to something like `->(a) { b }`. - Similarly, `a + b` is `->(a, b) { a + b }`. In both your example and mine, the operators (|> and +) could simply be replaced with appropriate methods (then and concat, respectively), depending on the context and desired functionality. ---------------------------------------- Feature #20770: A *new* pipe operator proposal https://bugs.ruby-lang.org/issues/20770#change-110023 * Author: AlexandreMagro (Alexandre Magro) * Status: Open ---------------------------------------- Hello, This is my first contribution here. I have seen previous discussions around introducing a pipe operator, but it seems the community didn't reach a consensus. I would like to revisit this idea with a simpler approach, more of a syntactic sugar that aligns with how other languages implement the pipe operator, but without making significant changes to Ruby's syntax. Currently, we often write code like this: ```ruby value = half(square(add(value, 3))) ``` We can achieve the same result using the `then` method: ```ruby value = value.then { add(_1, 3) }.then { square(_1) }.then { half(_1) } ``` While `then` helps with readability, we can simplify it further using the proposed pipe operator: ```ruby value = add(value, 3) |> square(_1) |> half(_1) ``` Moreover, with the upcoming `it` feature in Ruby 3.4 (#18980), the code could look even cleaner: ```ruby value = add(value, 3) |> square(it) |> half(it) ``` This proposal uses the anonymous block argument `(_1)`, and with `it`, it simplifies the code without introducing complex syntax changes. It would allow us to achieve the same results as in other languages that support pipe operators, but in a way that feels natural to Ruby, using existing constructs like `then` underneath. I believe this operator would enhance code readability and maintainability, especially in cases where multiple operations are chained together. Thank you for considering this proposal! -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/