-
Notifications
You must be signed in to change notification settings - Fork 17
Description
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 discussedskipwould 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)What do you think?