delegating to typed objects

Jeff Dyer jodyer at adobe.com
Mon Jul 9 14:19:59 PDT 2007




On 7/9/07 1:17 PM, Brendan Eich wrote:

> On Jul 9, 2007, at 12:10 PM, Jeff Dyer wrote:
> 
>>>> class C { var x : String; }
>>>>    c = new C;
>>>>    function F() {}
>>>>    F.prototype=c;
>>>>    f = new F; // f.__proto__ = c
>>>>    f.x =4;
>>>>   
>>>>  If you do this c.x now equals "4", that is the value is not set in f, but
>>>> it goes up the prototype chain and sets 4 into x (and does implicit
>>>> conversion). 
>>>>  
>>>>  
>> This behavior is incorrect. For compatibility with ES3, property writes must
>> be shallow.
> 
> Agreed, but the question is: how? If you say that f.hasOwnProperty('x'), then
> what is the type constraint on that property's value? If it is String, then
> how is it implemented given that new F creates an Object instance, not a C
> instance?
> 
Œx¹ is an expando on Œf¹ and therefore has no type constraint. Except for
the assigment to Œf.x¹, the value of f.hasOwnProperty(Œx¹) would be false.
> 
> One could imagine a fixture being added to each Object instance created by new
> F. It would make the type of f be {x:String}, which is compatible with C
> assuming you put 'public' in front of 'var x' (that's necessary, otherwise the
> x in c is in C's internal namespace -- please correct me if I have this
> wrong).
> 
> What's not allowed is an unconstrained slot on f -- that would break type
> safety for methods of C that count on x being a String. What also seems hard
> to believe in is some magic getter/setter pair in c (f.__proto__) that lets x
> be stored in each instance (f) but enforces the type constraint.
> 
But it could be allowed, just as the following is allowed when a method m is
added to the class C defined above,

> var o = {}
> o.g = F.prototype.m
> o.g ()

Œthis¹ is bound to Œc¹ in Œg¹.

> 
> So when you wrote "This behavior is incorrect", did you have in mind a fixture
> per instance, created on demand when assigning ("writes must be shallow") to x
> where f.__proto__.x is a fixture defined by C? I.e., a copy-on-write fixture
> due to the class of f differing (and lacking any public::x of its own) from
> the class of c?
> 
I had in mind that Œf.x¹ is an unconstrained expando property.
 
>>> If you want x to be a delegated and override-able "plain old" property, not
>>> a fixture, declare C thus:
>>>  
>>>  class C { prototype var x : String; }
>>>  
>>>  
>> To be clear, in the example above this would put a expando property Œx¹ on
>> Œf.__proto__.__proto__¹.
> 
> Yes, but it could be shadowed in f instances, inheriting the type constraint.
> 
>>  See my comment before my last one. Making prototypes more like classes would
>> make them less flexible, more complicated, and duplicate functionality that
>> is already available. I don¹t see the point, but maybe I¹m missing the use
>> case.
>> 
> 
> Using functions as extra constructors may be a use-case, but the primary
> problem is definitional: given functions and classes, what *should* happen in
> Kris's example, and how should it be specified/reference-implemented?
> Copy-on-write fixtures are a new thing under our Sun, it seems to me.
> 
See my comments above. There is no need for copy on write fixtures,  just a
plain old expando on Œf¹ for Œx¹. If you want type guarantees, use classes.
> 
> /be
> 
> 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.mozilla.org/pipermail/es-discuss/attachments/20070709/cd1f504e/attachment-0002.html 


More information about the Es4-discuss mailing list