May the defineProperty method of a proxy handler throw a TypeError?

classic Classic list List threaded Threaded
30 messages Options
12
Reply | Threaded
Open this post in threaded view
|

May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
I'm using a proxy to implement the DOM NodeList interface.  A NodeList
object is array-like and has read-only, non-configurable array index
properties.

In my handler's set() and delete() methods, I just return false if an
attempt is made to set or delete an indexed property.

The defineProperty() method is not parallel to set() and delete(),
however.  I can't just return false, since the return value is ignored.  
And I can't tell from the proposal whether I am allowed to throw a
TypeError from this method. In getOwnPropertyDescriptor() I know that I
have to lie and return a descriptor with configurable:true for the
indexed properties. So in defineProperty() should I just silently ignore
any attempts to set an indexed property, or should I actively reject
those attempts with a TypeError?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Tom Van Cutsem-3
Hi David,

The short answer: if you also define a 'set' trap, throwing a TypeError from defineProperty() to signal rejection is appropriate.

The longer answer:

defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9) whose rejection behavior depends on an explicit 'Throw' parameter, just like [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean success flag to determine their rejection behavior, while defineProperty() does not?

I believe that, until now, we were convinced that in the case of proxies, defineProperty() actually does _not_ depend on strict mode, because the built-in Object.defineProperty and Object.defineProperties methods (ES5 section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its 3rd argument 'Throw' set unconditionally to 'true', meaning it should never reject silently, independent of the strictness of the code.

However, checking other parts of the spec where [[DefineOwnProperty]] is invoked, I now notice it's also invoked by [[Put]], which passes its own 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw' argument is dependent on strict mode. This complicates matters because of derived traps.

If a proxy handler does _not_ define a 'set' trap (which is derived), the proxy implementation will fall back on the fundamental defineProperty() trap, whose rejection behavior in that context now _should_ depend on strict mode. However, the current defineProperty() API doesn't allow the programmer to express this.

I see two options here:
1) modify the defineProperty() trap such that it also returns a boolean flag to indicate rejection, like set() and delete(). This is still possible as defineProperty() currently has no useful return value.

2) specify unambiguously that defineProperty() on proxies should always reject explicitly by throwing a TypeError, even if the defineProperty() trap was called as part of the default 'set' trap.
This can be justified if we specify that the default 'set' trap invokes the 'defineProperty' trap as if by calling "Object.defineProperty", which is specified to never reject silently.

Option #1 would most closely follow the current ES5 spec, but would disallow the default 'set' trap behavior from being written in Javascript itself, since it's impossible to specify the value of the 'Throw' parameter in Javascript.

Option #2 is in line with how the current default 'set' behavior is specified at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.

Cheers,
Tom

2011/5/25 David Flanagan <[hidden email]>
I'm using a proxy to implement the DOM NodeList interface.  A NodeList object is array-like and has read-only, non-configurable array index properties.

In my handler's set() and delete() methods, I just return false if an attempt is made to set or delete an indexed property.

The defineProperty() method is not parallel to set() and delete(), however.  I can't just return false, since the return value is ignored.  And I can't tell from the proposal whether I am allowed to throw a TypeError from this method. In getOwnPropertyDescriptor() I know that I have to lie and return a descriptor with configurable:true for the indexed properties. So in defineProperty() should I just silently ignore any attempts to set an indexed property, or should I actively reject those attempts with a TypeError?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

seaneagan1
Is think it would beneficial to replace all this.* calls in the
default trap implementations with Object.* methods and syntax that
subsequently triggers the this.* calls.  This would guarantee that
none of the internal object semantics are being missed, and
implementations could still optimize just as easily.

On Thu, May 26, 2011 at 8:36 AM, Tom Van Cutsem <[hidden email]> wrote:

> Hi David,
> The short answer: if you also define a 'set' trap, throwing a TypeError from
> defineProperty() to signal rejection is appropriate.
> The longer answer:
> defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9)
> whose rejection behavior depends on an explicit 'Throw' parameter, just like
> [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean
> success flag to determine their rejection behavior, while defineProperty()
> does not?
> I believe that, until now, we were convinced that in the case of proxies,
> defineProperty() actually does _not_ depend on strict mode, because the
> built-in Object.defineProperty and Object.defineProperties methods (ES5
> section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its
> 3rd argument 'Throw' set unconditionally to 'true', meaning it should never
> reject silently, independent of the strictness of the code.
>
> However, checking other parts of the spec where [[DefineOwnProperty]] is
> invoked, I now notice it's also invoked by [[Put]], which passes its own
> 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw'
> argument is dependent on strict mode. This complicates matters because of
> derived traps.
> If a proxy handler does _not_ define a 'set' trap (which is derived), the
> proxy implementation will fall back on the fundamental defineProperty()
> trap, whose rejection behavior in that context now _should_ depend on strict
> mode. However, the current defineProperty() API doesn't allow the programmer
> to express this.
> I see two options here:
> 1) modify the defineProperty() trap such that it also returns a boolean flag
> to indicate rejection, like set() and delete(). This is still possible as
> defineProperty() currently has no useful return value.
> 2) specify unambiguously that defineProperty() on proxies should always
> reject explicitly by throwing a TypeError, even if the defineProperty() trap
> was called as part of the default 'set' trap.
> This can be justified if we specify that the default 'set' trap invokes the
> 'defineProperty' trap as if by calling "Object.defineProperty", which is
> specified to never reject silently.
> Option #1 would most closely follow the current ES5 spec, but would disallow
> the default 'set' trap behavior from being written in Javascript itself,
> since it's impossible to specify the value of the 'Throw' parameter
> in Javascript.
> Option #2 is in line with how the current default 'set' behavior is
> specified
> at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
> Cheers,
> Tom
> 2011/5/25 David Flanagan <[hidden email]>
>>
>> I'm using a proxy to implement the DOM NodeList interface.  A NodeList
>> object is array-like and has read-only, non-configurable array index
>> properties.
>>
>> In my handler's set() and delete() methods, I just return false if an
>> attempt is made to set or delete an indexed property.
>>
>> The defineProperty() method is not parallel to set() and delete(),
>> however.  I can't just return false, since the return value is ignored.  And
>> I can't tell from the proposal whether I am allowed to throw a TypeError
>> from this method. In getOwnPropertyDescriptor() I know that I have to lie
>> and return a descriptor with configurable:true for the indexed properties.
>> So in defineProperty() should I just silently ignore any attempts to set an
>> indexed property, or should I actively reject those attempts with a
>> TypeError?
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
>



--
Sean Eagan
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
In reply to this post by Tom Van Cutsem-3
On 5/26/11 6:36 AM, Tom Van Cutsem wrote:
Hi David,

The short answer: if you also define a 'set' trap, throwing a TypeError from defineProperty() to signal rejection is appropriate

Thanks.  I was worried that defineProperty() was required to honor property changes since getOwnPropertyDescriptor() is required to say that the properties are configurable.  (I've read the justification for that in the proposal multiple times, but I've never been able to understand it...)

The longer answer:

defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9) whose rejection behavior depends on an explicit 'Throw' parameter, just like [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean success flag to determine their rejection behavior, while defineProperty() does not?

I believe that, until now, we were convinced that in the case of proxies, defineProperty() actually does _not_ depend on strict mode, because the built-in Object.defineProperty and Object.defineProperties methods (ES5 section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its 3rd argument 'Throw' set unconditionally to 'true', meaning it should never reject silently, independent of the strictness of the code.

However, checking other parts of the spec where [[DefineOwnProperty]] is invoked, I now notice it's also invoked by [[Put]], which passes its own 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw' argument is dependent on strict mode. This complicates matters because of derived traps.

If a proxy handler does _not_ define a 'set' trap (which is derived), the proxy implementation will fall back on the fundamental defineProperty() trap, whose rejection behavior in that context now _should_ depend on strict mode. However, the current defineProperty() API doesn't allow the programmer to express this.

I see two options here:
1) modify the defineProperty() trap such that it also returns a boolean flag to indicate rejection, like set() and delete(). This is still possible as defineProperty() currently has no useful return value.

2) specify unambiguously that defineProperty() on proxies should always reject explicitly by throwing a TypeError, even if the defineProperty() trap was called as part of the default 'set' trap.
This can be justified if we specify that the default 'set' trap invokes the 'defineProperty' trap as if by calling "Object.defineProperty", which is specified to never reject silently.

Option #1 would most closely follow the current ES5 spec, but would disallow the default 'set' trap behavior from being written in Javascript itself, since it's impossible to specify the value of the 'Throw' parameter in Javascript.

Option #2 is in line with how the current default 'set' behavior is specified at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.

Cheers,
Tom

2011/5/25 David Flanagan <[hidden email]>
I'm using a proxy to implement the DOM NodeList interface.  A NodeList object is array-like and has read-only, non-configurable array index properties.

In my handler's set() and delete() methods, I just return false if an attempt is made to set or delete an indexed property.

The defineProperty() method is not parallel to set() and delete(), however.  I can't just return false, since the return value is ignored.  And I can't tell from the proposal whether I am allowed to throw a TypeError from this method. In getOwnPropertyDescriptor() I know that I have to lie and return a descriptor with configurable:true for the indexed properties. So in defineProperty() should I just silently ignore any attempts to set an indexed property, or should I actively reject those attempts with a TypeError?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
In reply to this post by seaneagan1
On 5/26/11 6:51 AM, Sean Eagan wrote:
> Is think it would beneficial to replace all this.* calls in the
> default trap implementations with Object.* methods and syntax that
> subsequently triggers the this.* calls.  This would guarantee that
> none of the internal object semantics are being missed, and
> implementations could still optimize just as easily.
>
With specification text "as if by calling the primordial Object.*
function"?  So that user modifications to Object.* are not observable?

Wouldn't that mean that a pure-JavaScript implementation of the default
traps would not be possible from a module that could not run at
interpreter startup?  (That may not be a goal that anyone has, of course.)

Personally, I think that proxies would be easier to reason about if no
distinction was made between fundamental and derived traps. I'd put that
distinction in an abstract Proxy.Handler class and then rename the
current Proxy.Handler to Proxy.ForwardingHandler.

     David

> On Thu, May 26, 2011 at 8:36 AM, Tom Van Cutsem<[hidden email]>  wrote:
>> Hi David,
>> The short answer: if you also define a 'set' trap, throwing a TypeError from
>> defineProperty() to signal rejection is appropriate.
>> The longer answer:
>> defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9)
>> whose rejection behavior depends on an explicit 'Throw' parameter, just like
>> [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean
>> success flag to determine their rejection behavior, while defineProperty()
>> does not?
>> I believe that, until now, we were convinced that in the case of proxies,
>> defineProperty() actually does _not_ depend on strict mode, because the
>> built-in Object.defineProperty and Object.defineProperties methods (ES5
>> section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its
>> 3rd argument 'Throw' set unconditionally to 'true', meaning it should never
>> reject silently, independent of the strictness of the code.
>>
>> However, checking other parts of the spec where [[DefineOwnProperty]] is
>> invoked, I now notice it's also invoked by [[Put]], which passes its own
>> 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw'
>> argument is dependent on strict mode. This complicates matters because of
>> derived traps.
>> If a proxy handler does _not_ define a 'set' trap (which is derived), the
>> proxy implementation will fall back on the fundamental defineProperty()
>> trap, whose rejection behavior in that context now _should_ depend on strict
>> mode. However, the current defineProperty() API doesn't allow the programmer
>> to express this.
>> I see two options here:
>> 1) modify the defineProperty() trap such that it also returns a boolean flag
>> to indicate rejection, like set() and delete(). This is still possible as
>> defineProperty() currently has no useful return value.
>> 2) specify unambiguously that defineProperty() on proxies should always
>> reject explicitly by throwing a TypeError, even if the defineProperty() trap
>> was called as part of the default 'set' trap.
>> This can be justified if we specify that the default 'set' trap invokes the
>> 'defineProperty' trap as if by calling "Object.defineProperty", which is
>> specified to never reject silently.
>> Option #1 would most closely follow the current ES5 spec, but would disallow
>> the default 'set' trap behavior from being written in Javascript itself,
>> since it's impossible to specify the value of the 'Throw' parameter
>> in Javascript.
>> Option #2 is in line with how the current default 'set' behavior is
>> specified
>> at<http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
>> Cheers,
>> Tom
>> 2011/5/25 David Flanagan<[hidden email]>
>>> I'm using a proxy to implement the DOM NodeList interface.  A NodeList
>>> object is array-like and has read-only, non-configurable array index
>>> properties.
>>>
>>> In my handler's set() and delete() methods, I just return false if an
>>> attempt is made to set or delete an indexed property.
>>>
>>> The defineProperty() method is not parallel to set() and delete(),
>>> however.  I can't just return false, since the return value is ignored.  And
>>> I can't tell from the proposal whether I am allowed to throw a TypeError
>>> from this method. In getOwnPropertyDescriptor() I know that I have to lie
>>> and return a descriptor with configurable:true for the indexed properties.
>>> So in defineProperty() should I just silently ignore any attempts to set an
>>> indexed property, or should I actively reject those attempts with a
>>> TypeError?
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
In reply to this post by David Flanagan-2
On 5/26/11 9:35 AM, David Flanagan wrote:
On 5/26/11 6:36 AM, Tom Van Cutsem wrote:
Hi David,

The short answer: if you also define a 'set' trap, throwing a TypeError from defineProperty() to signal rejection is appropriate

Thanks.  I was worried that defineProperty() was required to honor property changes since getOwnPropertyDescriptor() is required to say that the properties are configurable.  (I've read the justification for that in the proposal multiple times, but I've never been able to understand it...)

Responding to my own message...  I think I now understand the configurable property requirement of getOwnPropertyDescriptor.  Is it for conformance with these paragraphs from §8.6.2 of the ECMA-262 spec?

The [[GetOwnProperty]] internal method of a host object must conform to the following invariants for each property of the host object:
•    If a property is described as a data property and it may return different values over time, then either or both of the [[Writable]] and [[Configurable] attributes must be true even if no mechanism to change the value is exposed via the other internal methods.
•    If a property is described as a data property and its [[Writable]] and [[Configurable]] are both false, then the SameValue (according to 9.12) must be returned for the [[Value]] attribute of the property on all calls to [[GetOwnProperty]].


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Bruant-4
Le 26/05/2011 19:10, David Flanagan a écrit :
On 5/26/11 9:35 AM, David Flanagan wrote:
On 5/26/11 6:36 AM, Tom Van Cutsem wrote:
Hi David,

The short answer: if you also define a 'set' trap, throwing a TypeError from defineProperty() to signal rejection is appropriate

Thanks.  I was worried that defineProperty() was required to honor property changes since getOwnPropertyDescriptor() is required to say that the properties are configurable.  (I've read the justification for that in the proposal multiple times, but I've never been able to understand it...)

Responding to my own message...  I think I now understand the configurable property requirement of getOwnPropertyDescriptor.  Is it for conformance with these paragraphs from §8.6.2 of the ECMA-262 spec?
Yes it is.
In a way, this is the equivalent of what happens for Object.freeze. If you don't want to honor what it says, you can still throw an error saying you don't want to.

David

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Bruant-4
In reply to this post by David Flanagan-2
Le 26/05/2011 18:44, David Flanagan a écrit :
> On 5/26/11 6:51 AM, Sean Eagan wrote:
>> Is think it would beneficial to replace all this.* calls in the
>> default trap implementations with Object.* methods and syntax that
>> subsequently triggers the this.* calls.  This would guarantee that
>> none of the internal object semantics are being missed, and
>> implementations could still optimize just as easily.
We have been discussing whether this.trap was equivalent to Object.trap
(shorthand notation) and the conclusion was that there was no way to
distinguish both cases. I think there actually is.
If, in a handler, I do "this.defineProperty(23, {value:1})", there is no
conversion of the first argument to a string while there is if I
internally call "Object.defineProperty(proxy, 23, {value:1})"
There are probably other such cases.

And I agree with Sean. this.trap calls should be replaced with Object.*
calls


> With specification text "as if by calling the primordial Object.*
> function"?  So that user modifications to Object.* are not observable?
I would argue so.
(by the way, ES5 terminology says "built-in" where you say "primordial")


> Wouldn't that mean that a pure-JavaScript implementation of the
> default traps would not be possible from a module that could not run
> at interpreter startup?  (That may not be a goal that anyone has, of
> course.)
Is it a goal at all?
There are plenty of things that are not possible anymore after one
starts messing around with built-in. I wouldn't be shocked by adding
this one.
I will always be in favor that derived traps should be implementable
with pure JS in a fresh environment, but when the environment isn't
fresh, it don't think it's worth worrying about such a guarantee.


> Personally, I think that proxies would be easier to reason about if no
> distinction was made between fundamental and derived traps.
Based on my experience with proxies, there are very few cases which
really require to re-implement all traps. Reimplementing the
fundamentals and letting the engine handle inheritance + hasOwn trap is
handy.


> I'd put that distinction in an abstract Proxy.Handler class and then
> rename the current Proxy.Handler to Proxy.ForwardingHandler.
What do you call a "class" is is a constructor with some arguments?
Could you provide a code snippet of how you'd see it work.

Also, I think that this strawman
(http://wiki.ecmascript.org/doku.php?id=strawman:derived_traps_forwarding_handler)
is a first step toward what you're asking.
I've also raised the idea of renaming what is currently called
Proxy.Handler. It's still in discussion I think. I remember that Tom had
an idea, but I don't remember which.

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Andreas Rossberg-4
In reply to this post by Tom Van Cutsem-3
On a somewhat related note, I recently noticed that the semantics of
[[GetProperty]] and [[GetOwnProperty]], according to
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics,
contain a possible "reject" step, which doesn't seem to be
well-defined given that these method have no Throw parameter either.

/Andreas


On 26 May 2011 15:36, Tom Van Cutsem <[hidden email]> wrote:

> Hi David,
> The short answer: if you also define a 'set' trap, throwing a TypeError from
> defineProperty() to signal rejection is appropriate.
> The longer answer:
> defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9)
> whose rejection behavior depends on an explicit 'Throw' parameter, just like
> [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean
> success flag to determine their rejection behavior, while defineProperty()
> does not?
> I believe that, until now, we were convinced that in the case of proxies,
> defineProperty() actually does _not_ depend on strict mode, because the
> built-in Object.defineProperty and Object.defineProperties methods (ES5
> section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its
> 3rd argument 'Throw' set unconditionally to 'true', meaning it should never
> reject silently, independent of the strictness of the code.
>
> However, checking other parts of the spec where [[DefineOwnProperty]] is
> invoked, I now notice it's also invoked by [[Put]], which passes its own
> 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw'
> argument is dependent on strict mode. This complicates matters because of
> derived traps.
> If a proxy handler does _not_ define a 'set' trap (which is derived), the
> proxy implementation will fall back on the fundamental defineProperty()
> trap, whose rejection behavior in that context now _should_ depend on strict
> mode. However, the current defineProperty() API doesn't allow the programmer
> to express this.
> I see two options here:
> 1) modify the defineProperty() trap such that it also returns a boolean flag
> to indicate rejection, like set() and delete(). This is still possible as
> defineProperty() currently has no useful return value.
> 2) specify unambiguously that defineProperty() on proxies should always
> reject explicitly by throwing a TypeError, even if the defineProperty() trap
> was called as part of the default 'set' trap.
> This can be justified if we specify that the default 'set' trap invokes the
> 'defineProperty' trap as if by calling "Object.defineProperty", which is
> specified to never reject silently.
> Option #1 would most closely follow the current ES5 spec, but would disallow
> the default 'set' trap behavior from being written in Javascript itself,
> since it's impossible to specify the value of the 'Throw' parameter
> in Javascript.
> Option #2 is in line with how the current default 'set' behavior is
> specified
> at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
> Cheers,
> Tom
> 2011/5/25 David Flanagan <[hidden email]>
>>
>> I'm using a proxy to implement the DOM NodeList interface.  A NodeList
>> object is array-like and has read-only, non-configurable array index
>> properties.
>>
>> In my handler's set() and delete() methods, I just return false if an
>> attempt is made to set or delete an indexed property.
>>
>> The defineProperty() method is not parallel to set() and delete(),
>> however.  I can't just return false, since the return value is ignored.  And
>> I can't tell from the proposal whether I am allowed to throw a TypeError
>> from this method. In getOwnPropertyDescriptor() I know that I have to lie
>> and return a descriptor with configurable:true for the indexed properties.
>> So in defineProperty() should I just silently ignore any attempts to set an
>> indexed property, or should I actively reject those attempts with a
>> TypeError?
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
In reply to this post by David Bruant-4
On 5/26/11 10:46 AM, David Bruant wrote:
> Le 26/05/2011 18:44, David Flanagan a écrit :
>> I'd put that distinction in an abstract Proxy.Handler class and then
>> rename the current Proxy.Handler to Proxy.ForwardingHandler.
> What do you call a "class" is is a constructor with some arguments?
> Could you provide a code snippet of how you'd see it work.
All I really mean is that Proxy.Handler should be an object suitable for
use as a handler prototype. Rather than calling it Proxy.Handler, maybe
Proxy.DerivedTraps would be better. Then, using Allen's proposed <|
operator you could do:

p = Proxy.create(Proxy.DerivedTraps <| {
    // fundamental traps, and optionally some derived traps defined here
                            });
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Bruant-4
Le 26/05/2011 22:19, David Flanagan a écrit :
> On 5/26/11 10:46 AM, David Bruant wrote:
>> Le 26/05/2011 18:44, David Flanagan a écrit :
>>> I'd put that distinction in an abstract Proxy.Handler class and then
>>> rename the current Proxy.Handler to Proxy.ForwardingHandler.
>> What do you call a "class" is is a constructor with some arguments?
>> Could you provide a code snippet of how you'd see it work.
> All I really mean is that Proxy.Handler should be an object suitable
> for use as a handler prototype.
Are you suggesting a "generic" Proxy.Handler (or Proxy.DerivedTraps) or
something targeted for the forwarding handler use case.
For the forwarding handler use case, I think that [1] addresses what you
suggest.
For a generic handler object with generic methods, I think it's
pointless, because there is no such thing like a generic handler method.
However, if you have examples of what you think would be suitable for
generic handler methods, any handler object could inherit from, please
do share code snippets

> Rather than calling it Proxy.Handler, maybe Proxy.DerivedTraps would
> be better. Then, using Allen's proposed <| operator you could do:
>
> p = Proxy.create(Proxy.DerivedTraps <| {
>    // fundamental traps, and optionally some derived traps defined here
>                            });
Functionally, the current proposal is doing this (without the explicit
inheritance) with shorter syntax.

David

[1]
http://wiki.ecmascript.org/doku.php?id=strawman:derived_traps_forwarding_handler
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Tom Van Cutsem-3
In reply to this post by David Bruant-4


2011/5/26 David Bruant <[hidden email]>
Le 26/05/2011 18:44, David Flanagan a écrit :
> On 5/26/11 6:51 AM, Sean Eagan wrote:
>> Is think it would beneficial to replace all this.* calls in the
>> default trap implementations with Object.* methods and syntax that
>> subsequently triggers the this.* calls.  This would guarantee that
>> none of the internal object semantics are being missed, and
>> implementations could still optimize just as easily.
We have been discussing whether this.trap was equivalent to Object.trap
(shorthand notation) and the conclusion was that there was no way to
distinguish both cases. I think there actually is.
If, in a handler, I do "this.defineProperty(23, {value:1})", there is no
conversion of the first argument to a string while there is if I
internally call "Object.defineProperty(proxy, 23, {value:1})"
There are probably other such cases.

And I agree with Sean. this.trap calls should be replaced with Object.*
calls

The current API doesn't allow this as changing |this.*| to |Object.*| requires the handler to have access to the |proxy| in all traps. But if <http://wiki.ecmascript.org/doku.php?id=strawman:handler_access_to_proxy> is accepted, this seems like a good suggestion.

 
> With specification text "as if by calling the primordial Object.*
> function"?  So that user modifications to Object.* are not observable?
I would argue so.
(by the way, ES5 terminology says "built-in" where you say "primordial")


> Wouldn't that mean that a pure-JavaScript implementation of the
> default traps would not be possible from a module that could not run
> at interpreter startup?  (That may not be a goal that anyone has, of
> course.)
Is it a goal at all?
There are plenty of things that are not possible anymore after one
starts messing around with built-in. I wouldn't be shocked by adding
this one.
I will always be in favor that derived traps should be implementable
with pure JS in a fresh environment, but when the environment isn't
fresh, it don't think it's worth worrying about such a guarantee.

I agree. I think it would be good to specify the built-in implementation of derived traps to always invoke the built-in Object.* methods. This allows engines to fully optimize. It is still possible for JS programmers to faithfully implement the default behavior in JS, given a consistent environment (consistent meaning here that Object.* methods may even have been monkey-patched, but remain faithful to their ES5 semantics).
 
> Personally, I think that proxies would be easier to reason about if no
> distinction was made between fundamental and derived traps.
Based on my experience with proxies, there are very few cases which
really require to re-implement all traps. Reimplementing the
fundamentals and letting the engine handle inheritance + hasOwn trap is
handy.


> I'd put that distinction in an abstract Proxy.Handler class and then
> rename the current Proxy.Handler to Proxy.ForwardingHandler.
What do you call a "class" is is a constructor with some arguments?
Could you provide a code snippet of how you'd see it work.

Also, I think that this strawman
(http://wiki.ecmascript.org/doku.php?id=strawman:derived_traps_forwarding_handler)
is a first step toward what you're asking.
I've also raised the idea of renaming what is currently called
Proxy.Handler. It's still in discussion I think. I remember that Tom had
an idea, but I don't remember which.

My latest suggestion was to rename Proxy.Handler to Proxy.Forwarder (Proxy.ForwardingHandler is a mouthful).

The idea of the cited strawman would be that Proxy.Forwarder inherits from Proxy.BaseForwarder. BaseForwarder implements a forwarding implementation of all the fundamental traps. Forwarder then adds a forwarding implementation for the derived traps. Programmers can then create handlers that inherit from either one of these prototypal handlers, and override only a select number of traps, relying on the inherited implementation for the other traps. This seems to be in line with what David F. is proposing.

Cheers,
Tom
 

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Tom Van Cutsem-3
In reply to this post by Andreas Rossberg-4
Good catch. I count 5 occurrences of 'reject' on the page, 4 of these are called when the corresponding trap is not defined on the handler. For these cases, we should probably throw a TypeError, like we do for other traps (like for fix() in Object.freeze and getOwnPropertyNames in Object.getOwnPropertyNames).

For [[DefineOwnProperty]] and [[Delete]] I think we are unnecessarily conflating this error condition with the notion of 'rejection'. And as you note, for [[GetProperty]] and [[GetOwnProperty]] it isn't even well-defined.

2011/5/26 Andreas Rossberg <[hidden email]>
On a somewhat related note, I recently noticed that the semantics of
[[GetProperty]] and [[GetOwnProperty]], according to
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics,
contain a possible "reject" step, which doesn't seem to be
well-defined given that these method have no Throw parameter either.

/Andreas


On 26 May 2011 15:36, Tom Van Cutsem <tomvc.be@gmail.com> wrote:
> Hi David,
> The short answer: if you also define a 'set' trap, throwing a TypeError from
> defineProperty() to signal rejection is appropriate.
> The longer answer:
> defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9)
> whose rejection behavior depends on an explicit 'Throw' parameter, just like
> [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean
> success flag to determine their rejection behavior, while defineProperty()
> does not?
> I believe that, until now, we were convinced that in the case of proxies,
> defineProperty() actually does _not_ depend on strict mode, because the
> built-in Object.defineProperty and Object.defineProperties methods (ES5
> section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its
> 3rd argument 'Throw' set unconditionally to 'true', meaning it should never
> reject silently, independent of the strictness of the code.
>
> However, checking other parts of the spec where [[DefineOwnProperty]] is
> invoked, I now notice it's also invoked by [[Put]], which passes its own
> 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw'
> argument is dependent on strict mode. This complicates matters because of
> derived traps.
> If a proxy handler does _not_ define a 'set' trap (which is derived), the
> proxy implementation will fall back on the fundamental defineProperty()
> trap, whose rejection behavior in that context now _should_ depend on strict
> mode. However, the current defineProperty() API doesn't allow the programmer
> to express this.
> I see two options here:
> 1) modify the defineProperty() trap such that it also returns a boolean flag
> to indicate rejection, like set() and delete(). This is still possible as
> defineProperty() currently has no useful return value.
> 2) specify unambiguously that defineProperty() on proxies should always
> reject explicitly by throwing a TypeError, even if the defineProperty() trap
> was called as part of the default 'set' trap.
> This can be justified if we specify that the default 'set' trap invokes the
> 'defineProperty' trap as if by calling "Object.defineProperty", which is
> specified to never reject silently.
> Option #1 would most closely follow the current ES5 spec, but would disallow
> the default 'set' trap behavior from being written in Javascript itself,
> since it's impossible to specify the value of the 'Throw' parameter
> in Javascript.
> Option #2 is in line with how the current default 'set' behavior is
> specified
> at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
> Cheers,
> Tom
> 2011/5/25 David Flanagan <[hidden email]>
>>
>> I'm using a proxy to implement the DOM NodeList interface.  A NodeList
>> object is array-like and has read-only, non-configurable array index
>> properties.
>>
>> In my handler's set() and delete() methods, I just return false if an
>> attempt is made to set or delete an indexed property.
>>
>> The defineProperty() method is not parallel to set() and delete(),
>> however.  I can't just return false, since the return value is ignored.  And
>> I can't tell from the proposal whether I am allowed to throw a TypeError
>> from this method. In getOwnPropertyDescriptor() I know that I have to lie
>> and return a descriptor with configurable:true for the indexed properties.
>> So in defineProperty() should I just silently ignore any attempts to set an
>> indexed property, or should I actively reject those attempts with a
>> TypeError?
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
In reply to this post by Tom Van Cutsem-3
I'd like to follow up on this message from last month.  Has any decision been made about how a defineProperty() trap should reject the property definition attempt?  §4.6.4 of the latest WebIDL draft specifies a [[DefineOwnProperty]] algorithm with a Reject step that is dependent on the Throw argument.  And right now it can't really be implemented with a Proxy in a way that will work correctly when the proxy is used in non-strict code.

Tom suggested that defineProperty could return false or throw a TypeError to reject.  I assume that the proxy implementation would then do the right thing (return false or throw TypeError) based on the value of the Throw argument.

    David

On 5/26/11 6:36 AM, Tom Van Cutsem wrote:
Hi David,

The short answer: if you also define a 'set' trap, throwing a TypeError from defineProperty() to signal rejection is appropriate.

The longer answer:

defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9) whose rejection behavior depends on an explicit 'Throw' parameter, just like [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean success flag to determine their rejection behavior, while defineProperty() does not?

I believe that, until now, we were convinced that in the case of proxies, defineProperty() actually does _not_ depend on strict mode, because the built-in Object.defineProperty and Object.defineProperties methods (ES5 section 15.2.3.6-7) call the built-in [[DefineOwnProperty]] method with its 3rd argument 'Throw' set unconditionally to 'true', meaning it should never reject silently, independent of the strictness of the code.

However, checking other parts of the spec where [[DefineOwnProperty]] is invoked, I now notice it's also invoked by [[Put]], which passes its own 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw' argument is dependent on strict mode. This complicates matters because of derived traps.

If a proxy handler does _not_ define a 'set' trap (which is derived), the proxy implementation will fall back on the fundamental defineProperty() trap, whose rejection behavior in that context now _should_ depend on strict mode. However, the current defineProperty() API doesn't allow the programmer to express this.

I see two options here:
1) modify the defineProperty() trap such that it also returns a boolean flag to indicate rejection, like set() and delete(). This is still possible as defineProperty() currently has no useful return value.

2) specify unambiguously that defineProperty() on proxies should always reject explicitly by throwing a TypeError, even if the defineProperty() trap was called as part of the default 'set' trap.
This can be justified if we specify that the default 'set' trap invokes the 'defineProperty' trap as if by calling "Object.defineProperty", which is specified to never reject silently.

Option #1 would most closely follow the current ES5 spec, but would disallow the default 'set' trap behavior from being written in Javascript itself, since it's impossible to specify the value of the 'Throw' parameter in Javascript.

Option #2 is in line with how the current default 'set' behavior is specified at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.

Cheers,
Tom

2011/5/25 David Flanagan <[hidden email]>
I'm using a proxy to implement the DOM NodeList interface.  A NodeList object is array-like and has read-only, non-configurable array index properties.

In my handler's set() and delete() methods, I just return false if an attempt is made to set or delete an indexed property.

The defineProperty() method is not parallel to set() and delete(), however.  I can't just return false, since the return value is ignored.  And I can't tell from the proposal whether I am allowed to throw a TypeError from this method. In getOwnPropertyDescriptor() I know that I have to lie and return a descriptor with configurable:true for the indexed properties. So in defineProperty() should I just silently ignore any attempts to set an indexed property, or should I actively reject those attempts with a TypeError?

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Bruant-4
In reply to this post by Tom Van Cutsem-3
Le 26/05/2011 15:36, Tom Van Cutsem a écrit :

> Hi David,
>
> The short answer: if you also define a 'set' trap, throwing a
> TypeError from defineProperty() to signal rejection is appropriate.
>
> The longer answer:
>
> defineProperty() is based on [[DefineOwnProperty]] (ES5 section
> 8.12.9) whose rejection behavior depends on an explicit 'Throw'
> parameter, just like [[Put]] and [[Delete]]. Why then, do set() and
> delete() return a boolean success flag to determine their rejection
> behavior, while defineProperty() does not?
>
> I believe that, until now, we were convinced that in the case of
> proxies, defineProperty() actually does _not_ depend on strict mode,
> because the built-in Object.defineProperty and Object.defineProperties
> methods (ES5 section 15.2.3.6-7) call the built-in
> [[DefineOwnProperty]] method with its 3rd argument 'Throw' set
> unconditionally to 'true', meaning it should never reject silently,
> independent of the strictness of the code.
>
> However, checking other parts of the spec where [[DefineOwnProperty]]
> is invoked, I now notice it's also invoked by [[Put]], which passes
> its own 'Throw' argument to [[DefineOwnProperty]], and this time, the
> 'Throw' argument is dependent on strict mode. This complicates matters
> because of derived traps.
>
> If a proxy handler does _not_ define a 'set' trap (which is derived),
> the proxy implementation will fall back on the fundamental
> defineProperty() trap, whose rejection behavior in that context now
> _should_ depend on strict mode. However, the current defineProperty()
> API doesn't allow the programmer to express this.
>
> I see two options here:
> 1) modify the defineProperty() trap such that it also returns a
> boolean flag to indicate rejection, like set() and delete(). This is
> still possible as defineProperty() currently has no useful return value.
>
> 2) specify unambiguously that defineProperty() on proxies should
> always reject explicitly by throwing a TypeError, even if the
> defineProperty() trap was called as part of the default 'set' trap.
> This can be justified if we specify that the default 'set' trap
> invokes the 'defineProperty' trap as if by calling
> "Object.defineProperty", which is specified to never reject silently.
>
> Option #1 would most closely follow the current ES5 spec, but would
> disallow the default 'set' trap behavior from being written in
> Javascript itself, since it's impossible to specify the value of the
> 'Throw' parameter in Javascript.
>
> Option #2 is in line with how the current default 'set' behavior is
> specified
> at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
What about adding a "throw" argument to the defineProperty trap (and any
trap for which the equivalent internal method has a "throw" argument) ?
The engine would set the boolean value correctly depending on strict
mode or any relevant parameter. Trap writers can adapt their behavior
based on this boolean.

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan-2
On 6/17/11 3:05 PM, David Bruant wrote:
> What about adding a "throw" argument to the defineProperty trap (and any
> trap for which the equivalent internal method has a "throw" argument) ?
> The engine would set the boolean value correctly depending on strict
> mode or any relevant parameter. Trap writers can adapt their behavior
> based on this boolean.
>
> David
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics already
defines appropriate Reject behavior (return false or throw) for the
[[Put]] and [[Delete]] operations based on the return value of the put()
and delete() traps.  [[DefineOwnProperty]] is the only one that does not
allow it.

Given that the fixed properties proposal is adding a return value to
defineProperty, perhaps returning false would be a suitable way to
reject a property definition.

     David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Mark S. Miller-2


On Fri, Jun 17, 2011 at 3:47 PM, David Flanagan <[hidden email]> wrote:
On 6/17/11 3:05 PM, David Bruant wrote:
What about adding a "throw" argument to the defineProperty trap (and any
trap for which the equivalent internal method has a "throw" argument) ?
The engine would set the boolean value correctly depending on strict
mode or any relevant parameter. Trap writers can adapt their behavior
based on this boolean.

David
http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics already defines appropriate Reject behavior (return false or throw) for the [[Put]] and [[Delete]] operations based on the return value of the put() and delete() traps.

Yes, the reason is that a JavaScript callee cannot sense the strictness of its caller.


 
 [[DefineOwnProperty]] is the only one that does not allow it.

Given that the fixed properties proposal is adding a return value to defineProperty, perhaps returning false would be a suitable way to reject a property definition.

   David



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

David Bruant-4
In reply to this post by David Flanagan-2
Le 18/06/2011 00:47, David Flanagan a écrit :

> On 6/17/11 3:05 PM, David Bruant wrote:
>> What about adding a "throw" argument to the defineProperty trap (and any
>> trap for which the equivalent internal method has a "throw" argument) ?
>> The engine would set the boolean value correctly depending on strict
>> mode or any relevant parameter. Trap writers can adapt their behavior
>> based on this boolean.
>>
>> David
> http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics
> already defines appropriate Reject behavior (return false or throw)
> for the [[Put]] and [[Delete]] operations based on the return value of
> the put() and delete() traps.  [[DefineOwnProperty]] is the only one
> that does not allow it.
>
> Given that the fixed properties proposal is adding a return value to
> defineProperty, perhaps returning false would be a suitable way to
> reject a property definition.
I would see this as a weird semantic collision. If I return undefined,
should it be considered as a falsy value or an inappropriate property
descriptor? If I return {} or [], is it a truthy value or an invalid
property descriptor?
I would be much more in favor of traps closely following internal
methods signature, meaning add "Throw" arguments and let trap writers
decide of what they want to do with it. Following internal method
signature sounds a safer way to get around what you need to do.
Currently, the "Throw" argument seems bound to strictness (needs to be
proven, i do not know ES5 by heart), but who knows what it's going to be
used for in the future (what other contextual information will influence
its value)?

----
delete(a,Throw){
  if(Throw)
    throw new Error();
  else
    return false;
}

// VS

delete(a){
  return false;
}
----
I think it's more clear for the reader that an error can be thrown from
the former case. The latter case requires implicit knowledge and may be
harder to debug. Of course, this is very subjective as I have never had
the occasion to debug such a code.

David
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Mark S. Miller-2
On Fri, Jun 17, 2011 at 4:20 PM, David Bruant <[hidden email]> wrote:
[...]
I would be much more in favor of traps closely following internal
methods signature, meaning add "Throw" arguments and let trap writers
decide of what they want to do with it. Following internal method
signature sounds a safer way to get around what you need to do.

I agree with the general idea. But rather than make the traps conform to leaky internal spec methods, let's refactor the internal spec method signatures to conform to the less leaky signatures we've already achieved for the traps <http://wiki.ecmascript.org/doku.php?id=harmony:proxy_defaulthandler#alternative_implementation_for_default_set_trap>. 

In particular, everywhere we're currently passing in a boolean Throw argument (which does in fact always indicate strictness) we should instead be returning a boolean. Then, only the top level interface between special forms and internal methods need be concerned to turn a failure (false) into either a silent failure or a throw, depending on the strictness of the special form. All other internal methods need only propagate such failure reports back accurately.

 
Currently, the "Throw" argument seems bound to strictness (needs to be
proven, i do not know ES5 by heart), but who knows what it's going to be
used for in the future (what other contextual information will influence
its value)?

----
delete(a,Throw){
 if(Throw)
   throw new Error();
 else
   return false;
}

// VS

delete(a){
 return false;
}
----
I think it's more clear for the reader that an error can be thrown from
the former case. The latter case requires implicit knowledge and may be
harder to debug. Of course, this is very subjective as I have never had
the occasion to debug such a code.

David



--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: May the defineProperty method of a proxy handler throw a TypeError?

Tom Van Cutsem-3
In reply to this post by David Bruant-4
2011/6/18 David Bruant <[hidden email]>
Le 18/06/2011 00:47, David Flanagan a écrit :
> Given that the fixed properties proposal is adding a return value to
> defineProperty, perhaps returning false would be a suitable way to
> reject a property definition.

Yes, I think such an API could work.
 
I would see this as a weird semantic collision. If I return undefined,
should it be considered as a falsy value or an inappropriate property
descriptor? If I return {} or [], is it a truthy value or an invalid
property descriptor?

- |undefined| is falsy, so interpret as a reject.
- {} is a valid, empty property descriptor.
- For [], or any other non-falsy, non-object value either one could 1) ignore such values, 2) interpret them as 'rejects', or 3) interpret them as illegal property descriptors, which should trigger a TypeError. I would opt for 3), as if the internal Proxy code does:

let res = handler.defineProperty(...);
if (res) {
  desc = ToPropertyDescriptor(res); // throws TypeError if res is a non-Object value
  ...
} else {
  reject();
}

But before continuing this discussion, I'd like to take measure of how important it actually is for the Proxy API to be able to faithfully emulate ES5.1 reject behavior in non-strict mode. Say some non-strict ES5.1 code is executing Object.defineProperty(...) on a proxy and it throws a TypeError rather than failing silently. Is that a big deal or just a minor annoyance? As Mark recently mentioned, to ES5.1 code, proxies are like host objects, which may already trigger such behavior anyway. OTOH, it might preclude the use of Proxies to transparently wrap existing ES5.1 objects.

Cheers,
Tom

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12