delegating to typed objects

Kris Zyp kriszyp at xucia.com
Mon Jul 9 16:51:55 PDT 2007


You are right, it doesn't work for a Date, but it does work on an Array. The
incompatibility of calling setTime on the Date instance seems to have more
to do with the natural inclination to make primitives classes "final" (I am
not sure if they are in ES4, but in Java they are final) than class method
binding. While I am still hoping for option 1, I will say that throwing an
(incompatible object) error on f.m() seems more consistent than the other
possibilites that I have been countering: non-shallow assignments, automatic
this-binding, or preventing the assignment of prototype objects that happen
to be instances of user defined classes.
Kris


On 7/9/07, Brendan Eich <brendan at mozilla.org> wrote:
>
>  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/d4330291/attachment-0002.html 


More information about the Es4-discuss mailing list