I like goofy projects like this one but I think that if you insist on having calls there, then might as well make it more explicit with something like this:
Where `p` stands for Proxy to the previous result. Under the hood it would just return an object describing the name of the called method and arguments passed.
The pipe function would then iterate over the array, calling methods as described.
It's not immediately clear what should happen when a method's return type is a function, but I suppose this can be handled via convention.
Yeah, I did something similar in effect in Python some time ago: https://github.com/vollcheck/pypelines - this is a bytecode hack rather than operator overloading.
And call it a day. It does about 80% of what a pipe macro would do, has instant compatibility with other prototype methods and leads to very simple types. The only issue is that you have to define lambdas to call multivariable functions. D has got this very, very right.
It's certainly a nice usage of JavaScript's Proxy object and the resulting syntax is simple to grasp. Also glad to see the TS definitions in there. Well done!
For those that don't know. In Clojure it is also perfectly valid to drop the parantheses for each subsequent call in a threading macro if you don't want to pass in any additional arguments:
(-> x f g h)
If you need to pass an additional argument to g you can always do:
(-> x f (g foo) h)
There are thread first ->, thread last ->>, and even a thread as "as->" depending on where you want to place the argument when you pipe the result through the thread of functions.
The pipe function would then iterate over the array, calling methods as described.
It's not immediately clear what should happen when a method's return type is a function, but I suppose this can be handled via convention.
https://github.com/Tade0/pipe/blob/master/pipe-sync.js
Deleted Comment
https://github.com/mlajtos/es1995
https://github.com/tc39/proposal-pipeline-operator
See Clojure macros for thread-first `->`, thread-last `->>`, thread-as `as->`, `some->`, `some->>` and `cond->`: https://clojure.org/guides/threading_macros
You can leave all this hurt behind you and use ClojureScript, which compiles to JavaScript.
1: ~> being a pipe operator
2: Calling an async function from within an async function implies await
Without 2, it would look like this:
https://github.com/tc39/proposal-pipeline-operator