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

Need better names for two types of method extraction #13

Closed
js-choi opened this issue Oct 7, 2021 · 4 comments
Closed

Need better names for two types of method extraction #13

js-choi opened this issue Oct 7, 2021 · 4 comments
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed

Comments

@js-choi
Copy link
Collaborator

js-choi commented Oct 7, 2021

Method extraction (along with the calling of extracted methods) is a core use case of this proposal. For example, method extraction is essential for security from prototype pollution and other global mutation.

However, a non-goal of this proposal is what I currently call “tacit method extraction”: a (confusing) term I made up to refer to when a method is implicitly bound to its original owner, creating a bound function.

// “Explicit” method extraction results in a `this`-dependent ordinary function.
// This is handled by this proposal.
const { slice } = arr;
// The `this` value is supplied in the call.
arr::slice(...args);

// “Tacit” method extraction results in a `this`-independent bound function.
const slice = arr&.slice;
// The `this` value is not supplied in the call, because the function is bound.
slice(...args);

(Note that “tacit” method extraction is only useful on instance objects; it would not be useful on prototype objects, because calling a method on a prototype object is not very useful. In contrast, “explicit” method extraction is useful on prototype objects; the extracted prototype method could then be called on.)

// “Explicit” method extraction can extract from a prototype object…
const { slice } = Array.prototype;
// …and then a different `this` value may be supplied in the call.
arr::slice(...args);

I think these two concepts could use better names than “explicit” versus “tacit”. I don’t really have any other ideas, though.

(There’s even a third type of method extraction called “call-binding”, in which the this binding gets “uncurried” into a new (bound) function, using fn.call.bind, so that this is once again supplied at the call. @ljharb’s call-this call-bind library does this; Node’s primordials also use this pattern. I don’t even want to think about how they should fit in our nomenclature.)

@js-choi js-choi added documentation Improvements or additions to documentation help wanted Extra attention is needed labels Oct 7, 2021
@ljharb
Copy link
Member

ljharb commented Oct 7, 2021

call-bind, not call-this :-)

I'm confused why these need names. How you get to Array.prototype.slice isn't really relevant - it's the same function either way. The important point is that you can get it (which this proposal does not help or hinder), and then syntactically call it with an arbitrary array as the receiver.

@ljharb
Copy link
Member

ljharb commented Oct 7, 2021

Another way of saying it is, what I call "method extraction" is "call-bind a receiver-sensitive function, and cache it for later-run code".

A syntactic .call operator would obviate the need for call-binding, but not the rest.

@js-choi
Copy link
Collaborator Author

js-choi commented Oct 7, 2021

I'm confused why these need names. How you get to Array.prototype.slice isn't really relevant - it's the same function either way. The important point is that you can get it (which this proposal does not help or hinder), and then syntactically call it with an arbitrary array as the receiver.

Yeah, I’m just looking for a precise way to refer to the non-goal of not repeating ourselves when we do x::(x.m).

As you know, the old proposal allowed this with its unary form, ::x.m. That’s a non-goal of this proposal.

But I don’t want to call that non-goal simply “method extraction”. Some people may reasonably argue that this proposal does functionally address “method extraction”, in that we can extract method functions and then use them (const { foo } = obj0; obj1::foo(arg);. It’s just that, in one case (when the extractor and the receiver are the same: const { foo } = obj0; obj0::foo(arg)), you have to repeat yourself.

My concern about this confusion comes from #12 (comment) by theScottyJam:

Both pretty-format and graceful-fs are basically doing a form a method extraction, except in both cases they're choosing to supply the "this" value at the call location instead of the extract location.

This proposal stated that it doesn't wish to focus on method extraction, but ironically, I think this use case might be the most important one among the ones that have been analyzed.

My concern is that, if we say, “Method extraction is a non-goal of this proposal,” then some other people will also think erroneously that that non-goal includes const { foo } = obj0; obj1::foo(arg);. These people may think that “method extraction” includes use cases not necessarily involving call-bind.

@ljharb
Copy link
Member

ljharb commented Oct 7, 2021

Hmm, I see what you mean.

"Implicitly binding the receiver at extraction time is a non-goal of this proposal"?

@js-choi js-choi closed this as completed in cb778b2 Oct 7, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants