Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upCallable classes through proxies #402
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Feb 22, 2016
Member
It's feasible, sure, but I'm not sure it's desirable :) We have deliberately decided that a proxy only has a [[call]] and [[construct]] slot if the target has a [[call]] and [[construct]] slot. Is the behavior you want desirable because it allows you to implement call behavior using a proxy? If so I think waiting for a proposal to fix this is better than making some change to proxy invariants in the near term.
|
It's feasible, sure, but I'm not sure it's desirable :) We have deliberately decided that a proxy only has a [[call]] and [[construct]] slot if the target has a [[call]] and [[construct]] slot. Is the behavior you want desirable because it allows you to implement call behavior using a proxy? If so I think waiting for a proposal to fix this is better than making some change to proxy invariants in the near term. |
bterlson
added
question
normative change
labels
Feb 22, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nzakas
Feb 22, 2016
Is the behavior you want desirable because it allows you to implement call behavior using a proxy?
Yes. I guess the overall question is why lock down the class constructor so tightly? If a class constructor has no default [[Call]] or one that throws, then the current behavior (of throwing when new isn't called, and also the way proxies work) is maintained, and we now have a workaround.
I know callable class constructors are coming, I'm just unclear on why class constructors are so locked down right now when proxies let us override so many other default behaviors.
So, please don't take this as a proposal, just more of a question, is there a reason this is such a special case?
nzakas
commented
Feb 22, 2016
Yes. I guess the overall question is why lock down the class constructor so tightly? If a class constructor has no default I know callable class constructors are coming, I'm just unclear on why class constructors are so locked down right now when proxies let us override so many other default behaviors. So, please don't take this as a proposal, just more of a question, is there a reason this is such a special case? |
bterlson
removed
the
normative change
label
Feb 22, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Feb 22, 2016
Member
Class constructor is locked down tightly to be as future-compatible as possible with the eventual call-constructor proposal. You could imagine having proxies work around this issue, but it seems like a desirable aspect of proxies that they inherit the callability and constructability of the target. There is probably a similar future compatibility argument to be made as well. I'm not sure if this is a security-critical invariant of proxies so perhaps someone else can chime in on that front.
|
Class constructor is locked down tightly to be as future-compatible as possible with the eventual call-constructor proposal. You could imagine having proxies work around this issue, but it seems like a desirable aspect of proxies that they inherit the callability and constructability of the target. There is probably a similar future compatibility argument to be made as well. I'm not sure if this is a security-critical invariant of proxies so perhaps someone else can chime in on that front. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nzakas
Feb 23, 2016
Digging into this further, I see that this falls into the note on http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist:
A Proxy exotic object only has a [[Call]] internal method if the initial value of its [[ProxyTarget]] internal slot is an object that has a [[Call]] internal method.
So that explains why class constructors throw an error in this case.
Thanks!
nzakas
commented
Feb 23, 2016
|
Digging into this further, I see that this falls into the note on http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist:
So that explains why class constructors throw an error in this case. Thanks! |
nzakas
closed this
Feb 23, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Feb 23, 2016
Contributor
Class constructors have a [[Call]] internal method. So the example code should work in a ES2015/2016 compatible engine (after fixing the Person -> PersonProxy typo in var me = Person("Nicholas");).
|
Class constructors have a [[Call]] internal method. So the example code should work in a ES2015/2016 compatible engine (after fixing the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Feb 23, 2016
Member
I take it back, the reason it doesn't work is the call trap is called apply not call. Once renamed this works fine across all implementations.
|
I take it back, the reason it doesn't work is the call trap is called |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
nzakas
commented
Feb 24, 2016
|
Oh wow, I was doomed by typos. Thanks! |
nzakas commentedFeb 22, 2016
Digging through the spec, I found that there is
[[FunctionKind]]attribute that is set toclassConstructorfor class constructors, and it appears the sole purpose for this is to throw an error when you attempt to call a class constructor withoutnew(ref: http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist).I know the decision was made to not have class constructors callable, but prior to reading this part of the spec, I had expected this to work:
Of course, this won't work because
[[FunctionKind]]is still set to "classConstructor" and therefore throws an error.My question is: would it at all be feasible to allow proxies to be used in this way? It seems like the language could behave the same way by ensuring that class constructors don't have a
[[Call]]or has a[[Call]]that throws by default. That would the allow proxies to override that behavior and would eliminate the special case for class constructors.Just curious if that's remotely feasible?