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 <[EMAIL PROTECTED]> 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
_______________________________________________ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss