Hi! This proposal describes an interesting pattern with a few features and few of them is missed in the readme.
Reference transparency
// NO
setTimeout(() => resolve(value), ms);
// YES
setTimeout(resolve, ms, value);
One of the benefits of this codestyle is referential transparency, which mean that you nave NO unexpected issues with "value" mutation (if it "let" or "var", or some property). "resolve" will be called with exactly the passed "value" data, not with "value" state in the call time.
Unfortunately, almost none other APIs follow this arguments pattern. For example, you couldn't do this: somePromise.then(cb, otherParam). Partial application solves it: somePromise.then(cb~(?, otherParam)).
Reduce of extra computations
hugeList.forEach(x => doSome(a.b.c.d, x))
// VS
hugeList.forEach(doSome~(a.b.c.d, ?))
Here we have a complex data access (a.b.c.d) which could take some performance impact. Inline caches from an engine could solve it, until it comes to some computation, like some.getFrom('wat', 'wot'). Commonly, a good practice is moving a computation to a variable above, but this extra work is not cosy and a developer could forget about it.
This proposal solve it perfectly and it awesome, as I think.
Syntax
But adding an extra syntax for this feature is not worth it, from my side.
In other side, the main problem for implementing it as a new prototype method is that we need a way to mark empty arguments (?). What options do we have?
I propose to use special symbol for that (and lets call new method tie)
UPD: the first version of the proposed symbol name was empty, but as discussed skip would be better.
hugeList.forEach(x => doSome(a.b.c.d, x))
// VS
hugeList.forEach(doSome~(a.b.c.d, ?))
// VS
hugeList.forEach(doSome.tie(a.b.c.d, Symbol.skip))
Lazy operations
But that's not all!
We could reuse the symbol to perform other lazy operations:
// two traverse
list.filter((v) => v % 2).map((v) => v * 2)
// one traverse
list.map((v) => v % 2 ? v * 2 : Symbol.skip)
// not lazy
const sumOfFirstFive = list.reduce((acc, v, i) => i < 5 ? acc + v : acc, 0)
// lazy
const sumOfFirstFive = list.reduce((acc, v, i) => i < 5 ? acc + v : Symbol.skip, 0)
ramda reduced
What do you think?
Hi! This proposal describes an interesting pattern with a few features and few of them is missed in the readme.
Reference transparency
One of the benefits of this codestyle is referential transparency, which mean that you nave NO unexpected issues with "value" mutation (if it "let" or "var", or some property). "resolve" will be called with exactly the passed "value" data, not with "value" state in the call time.
Unfortunately, almost none other APIs follow this arguments pattern. For example, you couldn't do this:
somePromise.then(cb, otherParam). Partial application solves it:somePromise.then(cb~(?, otherParam)).Reduce of extra computations
Here we have a complex data access (
a.b.c.d) which could take some performance impact. Inline caches from an engine could solve it, until it comes to some computation, likesome.getFrom('wat', 'wot'). Commonly, a good practice is moving a computation to a variable above, but this extra work is not cosy and a developer could forget about it.This proposal solve it perfectly and it awesome, as I think.
Syntax
But adding an extra syntax for this feature is not worth it, from my side.
In other side, the main problem for implementing it as a new prototype method is that we need a way to mark empty arguments (
?). What options do we have?I propose to use special symbol for that (and lets call new method
tie)Lazy operations
But that's not all!
We could reuse the symbol to perform other lazy operations:
What do you think?