proposal-extensions
proposal-extensions copied to clipboard
Why $::util:toSet() equals to toSet($) but not toSet.cal($) in README "Example of using constructors or namespace object as extensions"?
// util.js
export const toSet = iterable => new Set(iterable)
import * as util from './util.js'
[]::util:toSet();// why here equals to `util.toSet([])`, but not `util.toSet.call([])`?
If so, why not use |> syntax instead?
In my opinion, value|>step1|>step2|>step3 syntax suits util that designed to use without other args,
while value::step1(true)::step2()::step3('yes', 1) syntax suits util that designed to use with other args.
The both proposals are mainly to avoid writting backward logic like step3(step2(step1(value))),
but do chain thing like $(value).step1().step2().step3() more easily, free, and fast.
If :: want to cover the use cases that |> does, and |> want to cover the multiple arguments use cases which should leave to ::, the situation would be a mess...
Extensions methods allow u chaining with normal methods in more ergonomics form. See https://johnhax.net/2020/tc39-nov-ext/slide#39
For example,
let classCount = document::allDivs
::flatMap(e => e.classList::toArray())
::toSet()::size
Any :: could be change to . (or vice versa) if there is real/extension methods u want to replace or insert. Changing to |> would ask many parens (because |> have very different operator precedence), and code reformatting. If not one and only one argument, there will be more codes to change (depending on which variant of pipeline u use and the pattern you adopt).
the situation would be a mess...
Basically, I believe extension methods/accessors have a simpler and consistent form with normal method call or property access, if your code is mainly oo-style or even multi-paradigm (like many code in the wild), this would be a better choice.
On the other hand, if your code is already fp-style (for example, use ramda or similar fp lib heavily), and rarely use oo-style, pipeline op may be better, though extensions-based value::pipe() could also be used instead of pipeline op.
Why
$::util:toSet()equals totoSet($)but nottoSet.call($)?
@hax Looking at src/design.md, this is no longer the case, right? According to the current design, $::util:toSet() would be transpiled to something like:
util.prototype.toSet.call($)
Maybe it would be good to close this issue, so that it doesn't confuse newcomers (such as myself)?
@m93a It's still in README:
https://github.com/tc39/proposal-extensions/blame/master/README.md#L64
@m93a You miss the line in the design.md:
If O is not a constructor, x::O:func(...args) roughly equals to O.func(x, ...args).
Maybe I should make it much clear in the document.
Oh, what a shame. I was hoping that this “syntax overloading” was dropped for a simpler and more consistent approach 😕️