Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?)
Mark S. Miller
erights at google.com
Sat Sep 29 21:36:21 PDT 2012
On Sat, Sep 29, 2012 at 5:17 PM, Brendan Eich <brendan at mozilla.org> wrote:
> Allen Wirfs-Brock wrote:
>
>> However, there is a bigger issue here. You could have asked a similar
>> question about Map.prototype. Why isn't Map.prototype a Map instances? Is
>> this a bug or an intentional design decision?
>>
>> Historically, the prototype objects associated with the 9 named built-in
>> constructors were all defined to be instances of those constructors. For
>> example, Boolean.prototype is a Boolean instance whose value is false.
>>
>> In writing the specification for Map, I intentionally deviated from that
>> pattern.
>>
>
> Failing to consult with implementors will just make editing churn. I don't
> remember much discussion on this change,
FWIW, this isn't a change from what we've discussed, it's a return to what
we've discussed. The proposals at
http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets
http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps
and
all the accepted class proposals including the recent maximin classes
use prototypes as Allen is now using them -- essentially as vtables, rather
than prototypical instances.
The fact that Date.prototype is a Date which therefore remains mutable
after freezing opened up a communications channel that SES closes at some
cost. Likewise with WeakMap.prototype on FF. Date.prototype is not a
working Date on IE and no one notices. RegExp.prototype used to not be a
RegExp, and no one noticed.
It's too late to make Date.prototype and RegExp.prototype not be Dates and
RegExps, but we should at least make them non-mutable once frozen. But
please let's not make the mistake with WeakMap.prototype, Map.prototype,
Set.prototype, and the prototype objects created for maximinimal classes.
> if any -- we did talk about the general problem of prototype objects being
> firstborns of their class, and how this makes them sometimes not just basis
> cases but degenerate cases.
>
> However, Map is prototyped in SpiderMonkey and V8. In SpiderMonkey, the
> prototype is a Map, not an Object:
>
> js> Object.prototype.toString.**call(Map.prototype).slice(8, -1)
> "Map"
>
> but you can't get, has, set, size, or iterate Map.prototype:
>
> js> Map.prototype.get('x')
> typein:2:0 TypeError: get method called on incompatible Map
> js> Map.prototype.has('x')
> typein:3:0 TypeError: has method called on incompatible Map
> js> Map.prototype.set('x', 42)
> typein:4:0 TypeError: set method called on incompatible Map
> js> Map.prototype.size()
> typein:5:0 TypeError: size method called on incompatible Map
> js> for (var [k, v] of Map.prototype) ;
> typein:6:13 TypeError: iterator method called on incompatible Map
>
> The error message is suboptimal but what's going on here is that
> Map.prototype has the SpiderMonkey equivalent of [[Class]] == "Map" (or the
> ES6 equivalent). This is important since all the builtins in ES3 + Reality
> (including RegExp; ES3 deviated there) make the prototype for built-in
> class C be of class C.
>
> Your change requires implementations to provide a different built-in class
> (constructor/prototype) initialization path. That's not desirable _per se_.
> Neither IMHO is the user-facing semantic split among "old" and "new"
> constructors.
>
> There are two separate issues here:
>
> 1. Should Map.prototype be an instance (firstborn for its realm) of class
> Map?
>
> 2. Should Map.prototype be a key/value store that can be used or abused as
> any other Map could be?
>
> We should not mix these up. SpiderMonkey (and possibly V8, I haven't
> tested) says "yes" to 1 and "no" to 2.
>
>
> I did not specify that Map.prototype is a Map instance. While it has
>> the methods that are applicable to Map instances it does not the internal
>> state that is necessary for those methods to actually work. For example,
>> if you try to store a value into Map.prototype by calling its set method,
>> you will get a TypeErrior according to the specification. May.prototype can
>> not be used as a map object.
>>
>
> That doesn't mean Map.prototype should not be classified as a Map per 1
> above.
>
>
> Why did I do this? Because, we are defining a significant number new
>> built-in "classes" and it is going to be increasingly hard to define
>> meaningful instance state for all such prototypes.
>>
>
> Not so, as shown above. It's trivial in SpiderMonkey to give the prototype
> no instance state and check for that. Alternative implementation techniques
> are feasible with different trade-offs.
>
> Cc'ing implementors.
>
> /be
>
>
> ______________________________**_________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/**listinfo/es-discuss<https://mail.mozilla.org/listinfo/es-discuss>
>
--
Cheers,
--MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120929/4d593fdc/attachment.html>
More information about the es-discuss
mailing list