3 ms·
A pipe operator compiles directly into the AST and completely disappears before execution. 64 |> Math.sqrt |> Math.sin Compiles in the AST to Math.
by hajile 8y ago
A pipe operator compiles directly into the AST and completely disappears before execution.
64 |> Math.sqrt |> Math.sin
Compiles in the AST to
Math.sin(Math.sqrt(64))
//curries variables away from functions
var realPipe = (a, ...args) => (...initParams) => {
var acc = a(...initParams);
for (var i = 0; i < args.length; ++i) {
acc = args[i](acc)
}
return acc;
}
//if first parameter is a function, curry to delay execution
//if first param is not a function, curry, but call immediately
var pipe = (a, ...args) =>
(typeof a === "function")
? realPipe(a, ...args)
: realPipe(...args)(a)
I'd note that this pipe implementation also bleeds its abstraction. JS has first-class functions, but this will never treat a function as data. You must be aware of how it works so if you are passing a function (for example, a getter function), you must manually curry it afterward.
This complication is why most pipe implementations don't actually mess with that data attribute part (they just skip to the realPipe implementation), but since the pipe operator can handle it, I figured I'd try to as well to show the issues.
- Spivak 8y agoI see no reason our function form couldn't do the same magic behind the scenes. Really no different from a lot of C compilers in this respect and with the bonus of an absolutely trivial polyfill.