typeof extensibility, building on my Value Objects slides from Thursday's TC39 meeting

Mark S. Miller erights at google.com
Fri Aug 2 16:57:32 PDT 2013


On Fri, Aug 2, 2013 at 3:02 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

>
> On Aug 2, 2013, at 12:59 PM, Tab Atkins Jr. wrote:
>
> On Fri, Aug 2, 2013 at 12:06 PM, Allen Wirfs-Brock
> ...
>
> 'size' is essentially a primitive of the key/value store.
>
>
> It can be defined in terms of iterations, but I'm fine with this being
> primitive because it's such a small data leak.  If you're subclassing
> Map such that the naive .size isn't what you want, you're doing
> something rather unusual.
>
>
> More importantly, if you actually have a reason to taking the size of a
> Map (perhaps to preallocate an ArrayBuffer to hold a copy of the values)
> then you probably would like to avoid iteration size performance hit to
> compute the size value.
>
> ...
>
>
> I'm less convinced of 'clear' - it's clearly a product of iteration +
> 'delete'.  You're right that it's often more efficient to do directly,
> though.
>
>
> Again it's pragmatics. If you have a reason for doing clears you probably
> want them to be fast.
>

As long as we're on this, I'd like to reiterate that we never achieved
consensus on adding .clear() to WeakMap, so its inclusion in the draft spec
is a bug. Further, as explained at <
http://wiki.ecmascript.org/lib/exe/fetch.php?media=meetings:relationships.pdf>,
when we go through the use cases, it becomes clear that an implementation
of WeakMap should always keep the associations on the key object, rather
than in the WeakMap, so that the typical case collects garbage without
needing to resort to the ephemeron collection algorithm. Adding .clear() to
WeakMap makes this implementation strategy substantially more expensive.

Leveraging Tab's point, adding .clear() to WeakMap is not pragmatics. It
fundamentally changes the nature of the abstraction.


>
>
> Yes.  You need exactly one of the iteration methods as a primitive.
> Today's world, where you have to override all four of them if you want
> to override any of them, feels very similar to forcing someone to
> override all six boolean comparisons rather than just defining them
> all in terms of less-than and equality.  (Like Brendan, I prefer the
> default to be one of the external iterators, either keys() or
> entries().)
>
>
> Sure, the four methods are trivial and all the actual semantics are in the
> "MapIterator" class.  The only reason you have to over-ride four methods is
> that in the current design the reference to the "MapIterator" constructor
> is private and hard coded.  They way we would do this in Smalltalk is to
> have an over-ridable getMapIterator (we wouldn't actually say "get")
> accessor property on Map.prototype (don't have one of those either...) that
> return the MapIterator factory.  You'd only over-ride that one accessor
> (plus write a new iterator and factory).
>
> I'd be fine with doing this approach.  I've generally, tried to minimize
> the number of OO hacks I've used in the spec. because not lot of people are
> familiar with them and others are uncomfortable with this style of
> extensibility.
>
>
> That is exactly the interface of ES6 Map except that Map adds the trivial
> iterator factory method.  It simply isn't worth having the added complexity
> of distinct Map and Map-lite classes simply to not have the iterator
> factory methods. For ES6 Map is Map-lite
>
>
> Except for the iterators and maybe 'clear', yes.
>
>
> and iterator can be fixed as above.
>
>
>
> We can debate whether future new methods should be added to Map or be made
> part of  distinct new classes.  I'd suggest the latter for most cases.  New
> methods are likely to incorporate domain concepts (eg, DOM stuff) that are
> not an essential part of the basic key/value store abstraction.  It's
> better to define an appropriate domain specific abstraction that
> encapsulates a Map (or if you're an old school OO'er subclasses it) than it
> is to start adding new methods.
>
>
> I find it quite likely that we'll add more Map methods in the future.
> For example, .update() from Python's dict is easy to write yourself,
> but it's useful *often enough* that it's likely worthwhile to add.
> Same with .pop(), .popitem(), and setdefault().  It bothers me that if
> an author monkey-patches these onto Map.prototype themselves, they'll
> automatically work on my subclass (because they're defined in terms of
> the primitives that I override), but if we then add it to the
> language, it'll break (because it's defined in terms of [[MapData]],
> which I can't intercept access to).
>
> (Though, Brendan says in his response that we probably shouldn't, and
> should instead just pledge to only add new methods onto Map
> subclasses.  I don't think that's a particularly good idea, but it
> would address most of my problem.)
>
>
> I agree that this is the preferred style of extensibility for both
> application developers and for libraries.  Creating an enhance/specialized
> subclass avoids unintentional usage and conflict.
>
>
> The even simpler course is to keep Map as spec'ed and make DOM or other
>
> specs work harder. Trade-offs...
>
>
> The reason I'm really pushing on this is that it's not just DOM (we've
>
> already made the trade-off there, by adding [MapClass] to WebIDL), but
>
> user-space as well.  I can't make a safe Counter class that's built on
>
> a Map unless I make the tradeoff above.
>
>
> Did you mean [[MapData]]?  [[MapData]] is just private state of the
> built-in object.  If you're saving that you can't safely define certain
> abstractions with access to private state mechanism, then I agree you.  But
> trying to turn [[MapData]] into an object level extension mechanism isn't
> the solution to your general problem.
>
>
> No, I mean [MapClass].
> <http://dev.w3.org/2006/webapi/WebIDL/#MapClass>  It's a WebIDL
> extended attribute - the syntax has no relation to your use of [[foo]]
> in the ES spec.  It declares the interface to be a Map subclass,
> setting Map.prototype on its prototype chain and providing default
> implementations of several Map methods for you.  (This is especially
> helpful on the spec level, as you can then just define what the map
> entries are and then methods like get() are auto-defined for you.)
>
>
> Other than the fact that WebIDL seems to continue to want to say
> "interface" when it really means "class", I don't have any problem with
> that. I suspect that in many cases it might be better  to encapsulate
> rather than subclass map but in situations where the primary concept is
> that of a specialized Map, this seems fine.
>
>
> Allen
>
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> 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/20130802/597f5ffa/attachment.html>


More information about the es-discuss mailing list