My response to the general comments are below.  I'll respond to comments for 
specific sections in separate messages. 


On Dec 29, 2012, at 2:37 PM, Tom Van Cutsem wrote:

> Hi,
> 
> I did a thorough revision of Allen's Rev12 and Rev13 drafts which incorporate 
> (among many other things) the refactored MOP, symbols, proxies and the 
> Reflect module in the ES6 draft.
> 
> Below is a long list of detailed comments, both editorial and more 
> substantial in nature.
> It's too cumbersome for me to file bugs for every individual comment. Allen, 
> please let me know what comments are worth filing a bug for.

This that may be subject to debate I'll wait until we seem to have resolution.  
Others, I'll either immediately fix or file a bug.

> 
> Before delving into the details, two more things:
> 
> First, thank you Allen for the great spec work. Overall I'm very happy with 
> the way proxies have been incorporated into the ES6 draft.
> 
> Second, if people want to comment on a particular issue, I suggest to rename 
> the topic and fork off a separate thread. That will be more manageable, and 
> will allow people that don't want to read through this whole list to follow 
> the separate discussions.
> 
> Cheers,
> Tom
> 
> == Comments based on ES6 draft Rev. 13 (21 dec. 2012) ==
> 
> === General remarks ===
> 
> * [[GetP]]/[[SetP]] => rename these to just [[Get]] and [[Set]]?

That's the plan, I just wanted to stage them through this transitional name to 
make sure any confusion is minimized

> 
> * [[GetInheritance]]/[[SetInheritance]] => why not [[GetProto]]/[[SetProto]]?
>   - More familiar to ECMAScript programmers
>   - No risk of confusion with function "prototype" property
>   - For ordinary objects, [[GetInheritance]] returns the value of the 
> [[Prototype]] field

[[GetProto]]/[[GetProto]] are plausible names. I struggled with these names.  I 
didn't want to use [[GetPrototype]]/[[SetPrototype]] possibly implying direct 
access to the [[Prototype]] internal data property because not all objects have 
that internal property and I also want to avoid confusion with the prototype 
property of  constructors.

I also considered GetParent/SetParent.

The way I arrived at "Inheritance" was from the internal use cases of these MOP 
methods.  The primarily use case for the Get is in climbing the "inheritance 
chain" in [[GetP]], [[SetP]], and   [[HasProperty]].  Note that these 
operations don't really care what model of inheritance (prototypal, class, 
multiple, etc.)  is implemented by an object.  They just need to ascertain 
which object they should delegate the lookup when they can't directly satisfy 
it.  Also, within the spec. we use the term "inherited property" as the 
alternative to "own property".  So, from that perspective, getting/setting an 
object's inheritance relationship seems like an appropriately abstract 
description of the purpose of these MOP methods.

That's said, I'm not in love with these names so I'd be happy to use some other 
names if we get some consensus building around them. 

> 
> * [[SetInheritance]]/Reflect.setPrototypeOf: I'm not sure this was agreed 
> upon. Especially since __proto__ is currently specified as a data property. 
> This means there is no setter that separately reifies the ability to set the 
> prototype. Thus, it's perfectly possible to just exclude [[SetInheritance]] 
> and Reflect.setPrototypeOf from the spec.

No, [[SetInheritence]] needs to be part of the MOP.  Certainly to define the 
semantics of __proto__ takes more than just saying it is a data property. 
Regardless of whether  it is ultimately reflected as that or as an accessor 
property the semantics of setting it has to be specified in some manner that 
likes it to the value that is retrieved by [[GetInheritance]].  Also, there are 
already in the spec. at least three forms of objects (ordinary, exotic symbols, 
exotic proxies) with different implementations of [[SetInheritance]] so an 
internal MOP method has already proven to be a useful specification device.

Whether or not it is reflected as a Proxy trap is a separate matter.  When this 
was discussed recently on es-discuss, the point was made that even if 
[[SetInhertance]] intersession by a trap is disallowed (ie, a trap can't 
prevent [[SetInheritance]] with the same value from being automatically invoked 
on the target) it is still important to get a notification that 
[[SetInheritiance]] has occurred. This is similar, to other traps whose handler 
behaviors are restricted but were still deemed useful from a notification 
perspective.  I believe that the conclusion of that discussion we seemed to 
have agreement that [[GetInhertiance]] should be handled in this same manner.

Reflect.setPrototypeOf is not essential and simply there to provide a point of 
further discussion. I think it is desirable that the Reflect.* interface be an 
accurate reflection of the internal MOP.  Any and all, restrictions that are 
applied to __prototype__ can also be applied to Reflect.setPrototypeOf.  In 
fact, the specification of it can be essentially:

  function setPrototypeOf(target, parent) {
    target.__proto__ = parent
  };

I'm also of the school that if we are going to accept a mutable inheritance 
chain as a standard part of the language then we might as well embrace it 
rather than treating is as the black sheep that we try to pretend isn't really 
there. 

> 
> * I'm a bit uncomfortable with the removal of property descriptor 
> normalization in the getOwnPropertyDescriptor/defineProperty traps. 
> Especially for getOwnPropertyDescriptor I think it's a breaking change w.r.t. 
> ES5.1.

To summarize, the [[GetOwnProperty]] internal method of proxy objects is now 
(in the spec draft) specified to take the descriptor object returned from the  
getOwnPropertyDescriptor trap and to package it up as an internal property 
descriptor record that is populated in the normal manner from the descriptor 
object.  The process of creating this PD record performs the same error checks 
that are performed (in ES5.1) by Object.defineOwnProperty.  In addition, the PD 
record now captures a reference to the original descriptor object.  If that PD 
record is subsequently used in a context where a descriptor object is required, 
the original captured descriptor object is used.  This is essential for 
expressing the semantics of Object.getOwnPropertyDescriptor in terms of the MOP 
while still enabling Proxies to extend of domain of property attributes.  
Object.getOwnPropertyDescriptor(obj) calls [[GetOwnProperty]] on obj which 
yields a PD record.  It then calls the abstraction operation Fr
 omPropertyDescriptor to produce the descriptor object that is its return 
value.  If obj is an ordinary object, the PD record produced by ordinary 
[[GetOwnProperty]] does not have a captured descriptor object so 
FromPropertyDescriptor cons up a new descriptor object that is a direct 
reflection of the PD record.  If obj is a proxy then [[GetOwnProperty]] will 
return a PD record that captures the descriptor object that was returned by the 
trap.  FromPropertyDescriptor simply returns that captured descriptor object 
which becomes the value of the original Object.getOwnPropertyDescriptor call.

This permits things like:

Object.defineOwnProperty(pObj1,"foo", {method: func});  //define property on a 
proxy-based object, that have "method" properties
console.log (Object.getOwnPropertyDescriptor(pObj1,"foo").method);    //we can 
retrieve the value of the method attribute (if the proxy supports it)

Object.defineOwnProperty(pObj2,"foo",Object.getOwnProperty(pObj1, "foo"));  
//copy a method properry from pObj1 to pObj2

If descriptor object with extended attributes is applied to an ordinary object, 
it is always first internally converted to a PD record.  PD records only 
contain fields for the ordinary attributes, and any operations upon ordinary 
objects will have no visibility  of  the extended attributes.

The only breaking change (relative to ES 5.1) possibility I see must start with 
the assumption that  ES5.1 property attributes are the final definition of 
property descriptor objects and that additional property attributes can never 
be added to the language (by the spec., not just via proxies) using any of the 
pre-existing ES5.1 APIs.  That seems quite unreasonable and was certainly not 
the intent when we introduced the reflection API into ES5.  In practice, ES 
code that manipulates property descriptors looking for specific attribute 
properties just won't see any extended attributes. Any code that iterates over 
all descriptor object properties  (for example, to display them in a debugger)  
will see them and treated them however the code is currently written, perhaps 
ignoring them, perhaps signaling an error, perhaps just processing then as a 
key/value pair.  In any case, the result will be exactly the same as if 
somebody manually constructs  such a descriptor object (such as 
 in the first line of the example above) and passes it into that same code 
today.


_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to