
Issue #20786 has been updated by matz (Yukihiro Matsumoto). Status changed from Open to Rejected We are discussing pipeline operator in #20770. IMO, this proposal does not make the code clearer nor more concise. Matz. ---------------------------------------- Feature #20786: Flow chaining with "then" keyword https://bugs.ruby-lang.org/issues/20786#change-110478 * Author: lpogic (Łukasz Pomietło) * Status: Rejected ---------------------------------------- Hi, I would like to propose using the *"then"* keyword to create chained flows. ### Background: Original idea: https://bugs.ruby-lang.org/issues/20770#change-110056 However, the concept has changed slightly since then. I now assume that rhs is only calculated when lhs is true, which seems more compatible with the current usage of *"then"* keyword. I would also like to move the discussion here as it may cause unnecessary chaos there. ### Basics: In the canonical version, *"then"* is used in a *"begin..end"* block to split it into steps. When the result of the last expression before *"then"* is not *"false"* or *"nil"*, it is passed as an argument to the next step. Otherwise, all subsequent steps are skipped. The result of the *"begin..end"* block is the result of the last expression, or *"false"*/*"nil"* if any step was skipped. ### Example: ``` ruby # original code source: https://github.com/ruby/ruby/blob/a6383fbe1628bdaa9ec6a30b3baa60dd7430b461/l... def include?(other) other = coerce_other(other) return false unless other.family == family begin_addr <= other.begin_addr && end_addr >= other.end_addr end # with chained flow def include?(other) begin coerce_other(other) then => coerced # then => name is my proposition of argument naming syntax return false unless coerced.family == family coerced then => it begin_addr <= it.begin_addr && end_addr >= it.end_addr end end ``` Please treat the canonical form as a starting point. As further improvements I would see: - implicit block argument name - implicit begin - beginless *"then"*, when lhs is just expression ### Example with futher improvements: ``` ruby def include?(other) coerce_other(other) then it.family == family ? it : false then begin_addr <= it.begin_addr && end_addr >= it.end_addr end # or def include?(other) coerce_other other then return false unless it.family == family begin_addr <= it.begin_addr && end_addr >= it.end_addr end end ``` ### *"then"* keyword as the pipeline operator: Under certain conditions, "then" could offer similar capabilities to the pipeline operator of functional languages: ``` ruby # assuming that "foo" and "bar" never return "false" or "nil" # instead of writing this: baz("string", bar(foo(), 2), 5) # you could write this: begin foo() then bar(it, 2) then baz("string", it, 5) end ``` -- https://bugs.ruby-lang.org/