Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why $::util:toSet() equals to toSet($) but not toSet.cal($) in README "Example of using constructors or namespace object as extensions"? #9

Open
LongTengDao opened this issue Mar 8, 2021 · 5 comments

Comments

@LongTengDao
Copy link

LongTengDao commented Mar 8, 2021

// 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...

@hax
Copy link
Member

hax commented Mar 8, 2021

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.

@cshaa
Copy link

cshaa commented Jun 2, 2021

Why $::util:toSet() equals to toSet($) but not toSet.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)?

@LongTengDao
Copy link
Author

@m93a It's still in README:

https://github.com/tc39/proposal-extensions/blame/master/README.md#L64

@hax
Copy link
Member

hax commented Jun 9, 2021

@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.

@cshaa
Copy link

cshaa commented Jun 9, 2021

Oh, what a shame. I was hoping that this “syntax overloading” was dropped for a simpler and more consistent approach 😕️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants