On Jul 18, 2011, at 7:24 PM, Axel Rauschmayer wrote:

>> From: Allen Wirfs-Brock <al...@wirfs-brock.com>
>> Date: July 18, 2011 19:32:24 GMT+02:00
>> To: es-discuss <es-discuss@mozilla.org>
>> Subject: An "extend" operator is a natural companion to <| 
> 
> 
> Definitely a nice dual to <|
> 
>> proto <| obj
> 
> 
> What happens if obj is not a literal? Then it would make sense to do a 
> shallow copy of obj whose prototype is proto. That would be useful for 
> combining objects into a chain.

That was my original thought, but for the proposal I limited to literal values 
on the RHS.  I did this to keep focus on the primary use cases and to not 
derail the feature with concerns about issues that don't occur in those primary 
use cases.   In particular there are some problematic issues relating to the 
concept of "shallow copy" of an arbitrary object.   What does that mean for 
host or Proxy based objects?  Is shallow copy a meaningful concept if the 
object uses closure capture to represent per object state? etc.

My think was that the feature could always be extended in the future to allow a 
non-literal RHS if we wanted to deal with those issues.


> 
> From your examples, it looks as if the lhs would be modified, a bit similar 
> to the += operator. Then the "arrow" should probably point in the opposite 
> direction, e.g.:
> 
>> objToBeModified +> increment

I don't follow your logic for the pointer direction. 


> 
> Quoting from your examples:
> 
>> function Point(x,y) {
>>    return tthis <& {
>>                   __x: x,
>>                   __y: y
>>                  };
>> };
>> Point.prototype <& {
>>    __validate(x,y) { return typeof x == 'number' && typeof y = 'number'}
>> };
> 
> 
> I love how the prototype is incremented here. What does "tthis" do? Wouldn't 
> point simply return an object literal (no "this <&")?

No, because the [[Construct]] internal method set this to a new object whose 
[[Prototype]] is correctly initialized to Point.prototype.  You could return:
   Point.prototype <| { ...

As shown, in the immediately following constructor-based Point3D example, if 
you are going to build inheritance hierarchies using constructors like this you 
need to call the "super class" constructor.  If you think it is a good idea (it 
probably is) to always follow a common pattern for constructors then Point 
probably should have been written as:

function Point(x,y) {
   return Object.call(this) <& {
                  __x: x,
                  __y: y
                 };
};


> 
> Another example from your message:
> 
>> const Point = {
>>      //private members
>>      __x: 0,
>>      __y: 0, 
>>      __validate(x,y) { return typeof x == 'number' && typeof y = 'number'},
>>      //public members
>>      new(x,y) {
>>           if (!this.__validate(x,y)) throw "invalid";
>>           return this <| {
>>                   __x: x,
>>                   __y: y
>>                  }
>>       };
>> }
> 
> If things are ever done this way, I would prefer to have an initialize() 
> method (that only initializes an instance that has been created for it) and 
> not a method that instantiates and initializes at the same time. initialize() 
> works together very well with super-references, because in subclasses, you 
> simply call the super-initialize method.

Lots of possible patterns for these things.  I was just trying to illustrate 
key use cases and not suggest a recommend pattern.

Allen

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

Reply via email to