Skip to content

Skip mark #53

@artalar

Description

@artalar

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions