Working pipe operator today in pure JavaScript
Implementation and Nature of the Hack
- Library abuses
Symbol.toPrimitive(often via aProxy) so that|and even other operators (/,*, etc.) are hijacked to build a pipeline, not perform bitwise/math operations. - Some see this as a “clever hack” and very much in the spirit of JavaScript experimentation; others say it’s “deeply wrong” to overload coercion semantics like this.
Ergonomics, Correctness, and DX
- The README’s initial example doesn’t work as written; you must retain a reference and then pipe using that reference, which is less ergonomic and more confusing.
- Chaining on one line for composition is criticized as hurting readability, diffs, and reviews; many expect pipes to be one operation per line.
- Using operators in this way can suggest mutation or destructive operations, which clashes with functional-programming expectations.
- Concerns that error messages will be confusing because syntax is being repurposed in non-obvious ways.
Relation to the Official Pipeline Operator
- Multiple comments are disappointed that the TC39 pipeline operator proposal has stalled; the F#-style variant is seen as the cleanest.
- Some argue this library demonstrates the demand and conceptual simplicity of a real pipe operator, but also why a “proper” language feature is preferable to hacks.
Do Pipes Solve a Real Problem?
- Skeptics say this is just syntax sugar for
f(x)/g(f(x))and that current patterns (.pipe(f,g,h),thrush(initial, ...funcs)) work fine. - Others argue pipes shine when composing many standalone functions (not methods on a prototype), especially to avoid prototype pollution or wrappers.
Complexity, Language Design, and Operator Overloading
- Some see this as further evidence that JavaScript is drifting toward C++-style “surprising” syntax and obscure coercion rules.
- C++-style operator overloading (and stream/bitshift reuse) is referenced as a cautionary tale; others defend operator overloading in math-heavy code.
- Clarification that this is not true operator overloading, but replacing coercion behavior—yet still perceived as similar in risk.
Alternatives, Ecosystem, and Tooling
- Comparable ideas: RxJS
.pipe, proxy-based fluent APIs, “Chute” (proxy + dot-notation), simpleObject.prototype.pipehelpers, or just functions. - Won’t work cleanly with TypeScript; some wish TS had operator overloading for math but not for general libraries.
- Rust-style testing of README examples is praised as a way to prevent example rot.
- Debugging pipelines is noted as harder; “tee”-style helpers are suggested but not demonstrated.