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

Reply via email to