Pipelining might be my favorite programming language feature
Existing pipeline features across languages
- Many comments point out that R (tidyverse and base
|>), Scala, C#, F#, Elixir, Clojure, Haskell, Kotlin, C++23 ranges, Hack, Gleam, Nushell, PowerShell, PRQL, Nix, and others already support some form of pipelining / threading / fluent APIs. - LINQ in C# and R’s tidyverse are held up as “gold standard” examples for readable, composable data transformations.
- Some highlight Scala’s and Kotlin’s extension methods / UFCS-like features as enabling “pipes without language support.”
- Shell pipelines and concatenative languages (Forth, Factor, Joy, APL-ish) are referenced as the conceptual ancestors where left‑to‑right composition is most natural.
Syntax, semantics, and terminology
- Several argue the article is really about syntax preferences, despite stating that “semantics beat syntax.”
- Disagreement over naming: “pipelining”, “method chaining”, “function composition”, “fluent interfaces”, “transducers”, “Thrush combinator” are all proposed; some feel “pipelining” is misleading given existing uses (CPU, Unix pipes).
- Debate over whether object method chaining and true function pipes are the same thing or just superficially similar.
Readability vs. imperative style
- Many find
data.iter().filter(...).map(...).collect()orx |> f |> gclearer than deeply nested calls or heavily indented functional code. - Others prefer explicit temporaries (
t1 = ...; t2 = ...;) as more readable, self-documenting, and friendlier to branching and comments. - Some note argument order conventions (Haskell-style vs. Rust-style) strongly affect how pleasant non-pipelined compositions look.
Debugging and tooling
- A recurring concern: long chains are harder to debug and to locate the failing step, especially without good debuggers.
- Counterpoint: pipelines are no worse than nested calls if tools allow breakpoints and inspection at any expression; languages/IDEs (C#, Rust, Clojure, JetBrains tools) are cited where this works reasonably well.
- Workarounds include “tap/inspect/peek” steps, splitting chains temporarily, or using REPL-style incremental building.
Error handling and types
- Some note pipelined monadic / result pipelines can obscure where an error originated if everything just propagates
null/error. - Others argue robust type-level error representations (Result/Either) and monadic patterns make pipelined error handling clearer than exceptions.
Pipelines beyond general-purpose code
- In SQL, people like PRQL-style or CTE-based pipelining as more honest about evaluation order and more composable than classic SELECT syntax.
- PowerShell’s typed object pipelines and Nushell’s similar approach are praised as richer than Unix byte streams.