delegating to typed objects

Brendan Eich brendan at mozilla.org
Mon Jul 9 16:16:56 PDT 2007


On Jul 9, 2007, at 3:22 PM, Jeff Dyer wrote:

>  On 7/9/07 2:42 PM, Kris Zyp wrote:
>
>> It seems to me that transfering bound methods to the function  
>> instances makes the situation equally confusing:
>> Now if write:
>> class C { var x : String; function m() : String { return this.x }}
>> c = new C;
>> function F() {}
>> F.prototype=c;
>> f = new F; // f.__proto__ = c
>> f.x =4;
>> f.m() -> ???
>> A Transferred bound method would mean that when we call f.m(),  
>> that the "this" in the method execution is actually c and not f.  
>> Does that really make sense?
>>
> Agreed. This presents a usability hazard. It has been suggested  
> that if ‘f’ is not compatible with class C, then an error should be  
> raised.

Kris asks where such an error would be raised. I would be surprised  
if it were anywhere other than F.prototype = c, but that is odd given  
that one can write ES3 code that sets, e.g. F.prototype = new Date.

> This might be an alternative that avoids the copying of fixtures or  
> other class like inheritance mechanisms to ensure type safety.

In your "f.x expando w/o type constraint shadows c.x" counter- 
proposal, there's no type safety problem for fixed methods of C --  
they can't be extracted without remembering their |this| binding, and  
when called (e.g., f.m()) on an incompatible type you should get a  
type error because |this| is type-constrained (as well as instance- 
bound) for fixed methods. Prototype methods as always have to  
constrain the type of |this|, or leave it * and do their own generic  
programming or checking.

I think we have only two courses:

1. Kris's proposal to make F construct instances of C. If C is not  
dynamic, these instances can't be decorated with expandos by (new F)  
or its callers.

2. Your proposal to avoid any magic implication of F.prototype = c,  
leaving f.x setting an unconstrained expando, leaving fixed methods  
of C this-bound to c, etc.

I think 2 is simpler but surprising (again consider F.prototype = new  
Date in ES3), and I'm not sure how much simpler since the refimpl has  
managed to do something different from either of the above (call it  
0. Set c.x when evaluating f.x = 4).

Having thought about 1 more, I'd like to point out that it's *not*  
what ES3 does:

js> function F(){}
js> F.prototype = d = new Date
js> f = new F
js> f.__proto__ === d
true
js> f.setTime(0)
typein:10: TypeError: Date.prototype.setTime called on incompatible  
Object

So new F did create an Object instance, and it linked its __proto__  
(ES1-3 [[Prototype]] internal property) to d. Not what Kris proposes  
by analogy to ES1-3, so I'm favoring 2 at the moment.

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


More information about the Es4-discuss mailing list