On Mar 17, 2012, at 8:39 AM, Claus Reinke wrote:

>>> 1. I don't like the imperative approximations of a declarative API.
>>> Since we're designing new language features, approximations
>>> should not be necessary.
>>> 
>>> There have been suggestions to interpret '<|' declaratively,
>>> and to avoid the special case for function rhs, ie, to interpret
>>> (p <| obj) simply as a structural representation of an object with
>>> un-nameable '[[prototype]]' field containing p.
>> 
>> You mean ditching function RHS completely or just not having it to specially 
>> treat LHS being function as well?
> 
> Neither. Currently, <| sets the [[prototype]] field of the RHS object,
> and -if the RHS is a function literal- also specifies the [[prototype]]
> field of objects generated from it. I suggest to remove that special
> case for function RHS.
> 
>>> What were the arguments against this?

(function () {}) creates two object, not one. We have to set the [[Prototype]] 
of both objects to something.  In deciding how to do this it is important to 
look at the role of each  member of that object pair.  The existing language 
defines a relationship between them that we need to respect.  We also need to 
consider what is going to be least surprising to users given the most common 
usage patterns. 

Consider 

  let F1 = function() {};
  F1.foo = "foo";
  F1.prototype.bar = "bar"

  let F2 = Fi <| function() {};

will a ES programmer expect F2.foo be be "foo" or undefined.  Understanding 
that <| defines the [[Prototype]] of the the function they should expect "foo".

What about
   (new F2).bar
will they expect "bar" or undefined. This is probably not something that they 
have thought about before, but I'm pretty confident that they will be 
astonished if they get undefined instead of "bar"

This has nothing to do with classes.  It is just basic prototypal inheritance 
and the semantics of the new operator and function expressions. 


>>> 
>>> 2. JS claims to be prototype-based but the 'prototype'-field really
>>> points to shared traits, while the actual cloning of prototypes into
>> It's probably too late to rename it to instanceTraits (I find the name 
>> 'prototype' unhappy, too)
>>> objects happens in the constructor functions. A deviation
>>> from Self (if I recall that correctly), it is a source of confusion.
>>> 
>>> If we combine the two points (cloning happens in the constructor,
>>> <| declares 'prototype' field), we get something like:
>>> 
>>> var Blah = function(){
>>> return BaseClass <| {
>>> a: function(){},
>>> b: function(){}
>>> }
>>> }
>> 
>> I'd say no to this -- ES is classless, but not true prototype oriented. I 
>> would keep the constructor-function-as-the-class-and-factory-at-once. Even 
>> if it is not optimal, but I think it is the cornerstone of ES object model.
> 
> If I'm not mistaken, the code above is valid in the current <| proposal
> (one might want to add a level of indirection to share a and b).
> 
> I'm not changing the constructor function approach, but the <| proposal
> makes it possible to specify the object [[prototype]] directly, without
> the indirection through the constructor function 'prototype'.
> 
> If working with functions wasn't so cumbersome in JS, and if <| wasn't
> limited to literal RHS (by making a shallow copy of the RHS, if necessary),
> the [[prototype]] setting could easily be abstracted out of the constructor,
> by function composition, without having to special-case function RHS in <|:
> 
> function compose(f,g) { .. }
> function extend(proto,constr) {
>   return compose(function(obj) { return proto <| obj }, constr)
> }
> var Blah = extend(BaseClass, function(){
>   return { a: function(){}, b: function(){} }
>   })
> 
> Of course, this would raise the question of whether the pattern is
> simple enough for code analyzers and optimizers to detect.. But mostly,
> the special case in <| is an artifact of function manipulation being too
> inconvenient in JS, and of <| being limited to literals (which is an
> artifact of object cloning being considered tricky).

Even more so it is a matter that array, function, and RegExp objects have 
special semantics ("internal methods") that are not obtained via prototype 
inheritance and those literal forms imply the use of those special semantics.  
If you want to clone object (and compose objects) you have to worry about the 
"internal methods" and whether or not you want them to propagate to the clones 
or what it would mean to compose objects with conflicting internal methods.

Restricting <| to literals on the RHS was done to keep it a tractable problems 
for Es6.



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

Reply via email to