You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First of all, I'm strongly supportive of the bind operator things, it is a very good supplementary to the language. Both this proposal and extension proposal has a very similar motivation and similar design, similar semantics on the :: operator. @hax mentioned that the parallel namespace is not an essential part of the extension proposal and can be removed under the temperature of the committee. And the significant difference between the two proposals is the semantics of binding accessors. I'm wondering if it is better for two proposals to collaborate and find a consensus?
@legendecas: Thanks for raising this! @hax (the champion of Extensions) and I have indeed been discussing privately, since August, about ways to reconcile our two proposals. (See also my detailed comparison document.)
I think it would be a great idea for us to continue those discussions publicly in this issue, though.
(@hax has said that their free time will be scarce over the next several months, which I will definitely try to respect with regards to advancing this proposal. ^_^)
The major differences seem to be the namespace, extraction, and special affordance for getters/setters. The former has strong pushback, the middle doesn't seem to have compelling motivation yet, and the latter doesn't seem to warrant special treatment (this is a combo of my opinion and my estimation of committee temperature).
@hax has said that they are open to dropping the special namespace (not sure about the special polymorphic extraction/calling syntaxes)—it’s the special treatment of getters/setters that’s the crux, perhaps.
Bind-this has no special variable namespace (but @hax is willing to drop this).
Bind-this has no implicit syntactic handling of property accessors.
Bind-this has no polymorphic const ::{ … } from …; syntax.
Bind-this has no polymorphic …::…:… syntax.
Bind-this has no Symbol.extension metaprogramming system.
@hax is willing to drop the first difference, but I’m not yet sure whether he would be willing to drop anything else from the list above. But I plan to keep engaging with him over the next few months, time permitting.
An update: I, @tabatkins, and @hax recently wrote articles about the dataflow proposals, including bind-this and Extensions, and TC39 also held two two meetings about the dataflow proposals:
Note, as the recent change from bind-this to call-this, the semantic of this proposal is now the subset of extensions proposal, and the syntax of this proposal also could be compatible with extensions proposal, if we choose "receiver-first style (bracketed)" like rec::[fn](arg0). ( :: is bikeshed, if we choose ->, it would be rec->[fn](arg0). )
I must say I really dislike the bracketed syntax. Using parenthesis (rec::(getFn())(arg0)) should be allowed, but not required for identifiers (rec::fn(arg0)) and member expressions (rec::namespace.fn(arg0), rec::namespace["fn"](arg0)).
@bergus As extensions proposal, it also have rec::method() syntax so the pair of rec::method() and rec::[method]() is actually mapping the rec.method() and rec[method]() syntax.
@hax Are you referring to this thing? I don't quite understand why rec::[method]() uses bracket syntax - it doesn't appear to evaluate method to a property name. I think it would make sense in rec::namespace:[nameExpr](...args), desugaring to Call(GetOwnProperty(namespace, nameExpr).value, rec, args) (or GetExtension instead of GetOwnProperty), but not without a namespace object in which the property name is resolved (since we don't want to resolve it on the receiver).
Syntax rec::method / rec::[method] choose [] is just for matching v.method / v[method]. But you are right, rec::[method] doesn't evaluate method to key but evaluate method to the method (or accessor) directly.
Of coz, we could consider other brackets syntax if we want to keep [x] alway mean evaluating key: rec::(method), rec::{method}, rec::${method} (pattern match proposal use syntax like that) or even rec::<method> (turbofish! 😂 ), it's just like the current escape hatch syntax of decorators@(decorator).
Syntax rec::method / rec::[method] choose [] is just for matching v.method / v[method]. But you are right, rec::[method] doesn't evaluate method to key but evaluate method to the method (or accessor) directly.
(For what it’s worth, I actually see some value in an analogy of bound functions acting as pseudo-“methods” of their objects, with the original functions acting as pseudo-“keys”. For example, in rec::fn(), the fn would be acting like a “key” on the “method” rec::fn, before being called.
However, I got some pushback from some others in the Committee about this analogy, so I dropped my pushing it.)
@js-choi I think the problem may be "bound" is unrelated semantic (of method), and I'm not sure the pushback is because such analogy, my impression is some delegates don't like "free" method. Actually I also feel "free" methods are not common in JS ecosystem, this is why extensions have a special syntax constraints to make it not as "free" as normal functions, one of my design goal is to make the extension users can only use extension methods as "method", not "function" by default.
I must say I really dislike the bracketed syntax. Using parenthesis (rec::(getFn())(arg0)) should be allowed, but not required for identifiers (rec::fn(arg0)) and member expressions (rec::namespace.fn(arg0), rec::namespace["fn"](arg0)).
If we require parens for member expressions, that to me drops the biggest conflict with the extensions proposal, which includes a way to do extension getters/setters.
We lose nothing by accepting this requirement. It avoids a whole lot of potential precedence confusion, avoids conflict with the extensions proposal, and doesn't block us from removing parens later if we feel that is justified.
I suppose I'm comfortable with the parens, but the extensions proposal's current proposed solution (a parallel binding namespace) is an utter nonstarter, and I've yet to see a direction for that proposal that is worth further discussion. If that proposal has something different in mind, then it'd be great to see these two work together.
That said, this one is more basic and simpler, so I think it would be perfectly fine to advance this one as-is and let the extensions proposal adapt around it.
@js-choi : I plan to remove "parallel binding namespace", only keep syntax like obj.ext%%prop (%% as a placeholder) in extensions proposal. I hope it could not only solve @ljharb 's concern, but also make extensions and call-this complementary.
Activity
js-choi commentedon Oct 27, 2021
@legendecas: Thanks for raising this! @hax (the champion of Extensions) and I have indeed been discussing privately, since August, about ways to reconcile our two proposals. (See also my detailed comparison document.)
I think it would be a great idea for us to continue those discussions publicly in this issue, though.
(@hax has said that their free time will be scarce over the next several months, which I will definitely try to respect with regards to advancing this proposal. ^_^)
ljharb commentedon Oct 27, 2021
The major differences seem to be the namespace, extraction, and special affordance for getters/setters. The former has strong pushback, the middle doesn't seem to have compelling motivation yet, and the latter doesn't seem to warrant special treatment (this is a combo of my opinion and my estimation of committee temperature).
Are there other differences I've missed?
js-choi commentedon Oct 27, 2021
@hax has said that they are open to dropping the special namespace (not sure about the special polymorphic extraction/calling syntaxes)—it’s the special treatment of getters/setters that’s the crux, perhaps.
nkitku commentedon Nov 11, 2021
js-choi commentedon Nov 12, 2021
js-choi commentedon Nov 12, 2021
As the extensions section (and the in-depth comparison) say, the concrete
differences between bind-this and extensions are currently:
const ::{ … } from …;syntax.…::…:…syntax.Symbol.extensionmetaprogramming system.@hax is willing to drop the first difference, but I’m not yet sure whether he would be willing to drop anything else from the list above. But I plan to keep engaging with him over the next few months, time permitting.
js-choi commentedon Mar 18, 2022
An update: I, @tabatkins, and @hax recently wrote articles about the dataflow proposals, including bind-this and Extensions, and TC39 also held two two meetings about the dataflow proposals:
We will discuss the two proposals further at the next plenary at the end of this month.
hax commentedon Mar 29, 2022
Note, as the recent change from bind-this to call-this, the semantic of this proposal is now the subset of extensions proposal, and the syntax of this proposal also could be compatible with extensions proposal, if we choose "receiver-first style (bracketed)" like
rec::[fn](arg0). (::is bikeshed, if we choose->, it would berec->[fn](arg0). )bergus commentedon Mar 29, 2022
I must say I really dislike the bracketed syntax. Using parenthesis (
rec::(getFn())(arg0)) should be allowed, but not required for identifiers (rec::fn(arg0)) and member expressions (rec::namespace.fn(arg0),rec::namespace["fn"](arg0)).hax commentedon Mar 29, 2022
@bergus As extensions proposal, it also have
rec::method()syntax so the pair ofrec::method()andrec::[method]()is actually mapping therec.method()andrec[method]()syntax.js-choi commentedon Mar 29, 2022
See also #10 (comment). At plenary, the Committee weakly preferred tight unbracketed receiver-first syntax.
bergus commentedon Mar 30, 2022
@hax Are you referring to this thing? I don't quite understand why
rec::[method]()uses bracket syntax - it doesn't appear to evaluatemethodto a property name. I think it would make sense inrec::namespace:[nameExpr](...args), desugaring toCall(GetOwnProperty(namespace, nameExpr).value, rec, args)(orGetExtensioninstead ofGetOwnProperty), but not without a namespace object in which the property name is resolved (since we don't want to resolve it on the receiver).hax commentedon May 24, 2022
@bergus Yes.
v::ns:[expr]is also possible, or required if we have strong symbol use cases (see tc39/proposal-extensions#11).Syntax
rec::method / rec::[method]choose[]is just for matchingv.method / v[method]. But you are right,rec::[method]doesn't evaluatemethodto key but evaluatemethodto the method (or accessor) directly.Of coz, we could consider other brackets syntax if we want to keep
[x]alway mean evaluating key:rec::(method),rec::{method},rec::${method}(pattern match proposal use syntax like that) or evenrec::<method>(turbofish! 😂 ), it's just like the current escape hatch syntax of decorators@(decorator).js-choi commentedon Jul 10, 2022
(For what it’s worth, I actually see some value in an analogy of bound functions acting as pseudo-“methods” of their objects, with the original functions acting as pseudo-“keys”. For example, in
rec::fn(), thefnwould be acting like a “key” on the “method”rec::fn, before being called.However, I got some pushback from some others in the Committee about this analogy, so I dropped my pushing it.)
hax commentedon Jul 11, 2022
@js-choi I think the problem may be "bound" is unrelated semantic (of method), and I'm not sure the pushback is because such analogy, my impression is some delegates don't like "free" method. Actually I also feel "free" methods are not common in JS ecosystem, this is why extensions have a special syntax constraints to make it not as "free" as normal functions, one of my design goal is to make the extension users can only use extension methods as "method", not "function" by default.
ewinslow commentedon Mar 16, 2026
If we require parens for member expressions, that to me drops the biggest conflict with the extensions proposal, which includes a way to do extension getters/setters.
We lose nothing by accepting this requirement. It avoids a whole lot of potential precedence confusion, avoids conflict with the extensions proposal, and doesn't block us from removing parens later if we feel that is justified.
js-choi commentedon Mar 16, 2026
I’m open to requiring parentheses around property access chains in call-this’s RHS, in the spirit of compatibility with the extensions proposal.
And the RHS parentheses can always be made optional for property chains, if the extensions proposal does not eventually progress.
I would also be interested to know how @ljharb feels about this restriction for his use cases.
ljharb commentedon Mar 16, 2026
I suppose I'm comfortable with the parens, but the extensions proposal's current proposed solution (a parallel binding namespace) is an utter nonstarter, and I've yet to see a direction for that proposal that is worth further discussion. If that proposal has something different in mind, then it'd be great to see these two work together.
That said, this one is more basic and simpler, so I think it would be perfectly fine to advance this one as-is and let the extensions proposal adapt around it.
hax commentedon Mar 26, 2026
@js-choi : I plan to remove "parallel binding namespace", only keep syntax like
obj.ext%%prop(%%as a placeholder) in extensions proposal. I hope it could not only solve @ljharb 's concern, but also make extensions and call-this complementary.