From: "AlexandreMagro (Alexandre Magro) via ruby-core" Date: 2024-11-29T18:19:54+00:00 Subject: [ruby-core:120062] [Ruby master Feature#20770] A *new* pipe operator proposal Issue #20770 has been updated by AlexandreMagro (Alexandre Magro). austin (Austin Ziegler) wrote in #note-50: > As I said, I don't think Ruby needs a pipe operator, but I wonder if a *different* approach might be taken. In irb, `_` is automatically assigned the result of the previous expression (well, expression *line*; it doesn't carry *within* an expression). What if that was done for Ruby as a whole? That is, `v = foo.bar && Integer.sqrt(_)` would be the same as `v = foo.bar && Integer.sqrt(foo.bar)` because `_` would be the value of `foo.bar`. > > Similarly, you could get a pipeline behaviour without any extra syntax elements: > > ```ruby > "https://api.github.com/repos/ruby/ruby" > URI.parse(_) > Net::HTTP.get(_) > JSON.parse(_) > _.fetch("stargazers_count") > puts "Ruby has #{_} stars" > ``` > > It would *substantially* complicate parsing (one would only want to "assign" `_` if an expression *uses* it), and right now `_` is a valid variable name (if usually used for an unused parameter). Using the "last expression result" as a global behavior could introduce unnecessary performance overhead, as the interpreter would need to track and update it for every expression. Furthermore, by explicitly using the pipe operator, the "last expression result" gains a clear meaning on its own, and no longer remains just an anonymous placeholder (`_`). This avoids the ambiguity that may arise in the code, which isn't an issue when writing expressions line by line in irb. ---------------------------------------- Feature #20770: A *new* pipe operator proposal https://bugs.ruby-lang.org/issues/20770#change-110800 * 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/