[Bug 20019] Support subclassing ES6 Map
Mark S. Miller
erights at google.com
Tue Nov 20 13:06:29 PST 2012
On Tue, Nov 20, 2012 at 12:30 PM, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
> On Tue, Nov 20, 2012 at 10:57 AM, Mark S. Miller <erights at google.com> wrote:
>> Speaking only for myself at this point -- I do not recall MultiMap
>> previously being suggested to the committee.
>> I think adding a MultiMap API to ES7 is a good idea. Neither Map nor
>> MultiMap should be a subclass of the other, since neither is an LSP
>> subtype of the other.
> When properly designed, as long as you interact with it only through
> Map methods, a MultiMap can be an LSP subtype of Map.
> This means that get() should grab the first value, if one exists, or
> undefined otherwise, while a separate method (getAll?) returns a
> (potentially empty) list of all values. set() should take only a
> single value, and wipe out all other values currently attached to the
> key. (Or, be n-ary and *replace* values at corresponding indexes.
> Given get()'s behavior, this is behaviorally indistinguishable from a
> plain Map, even if multiple values already exist on a key.) delete()
> should wipe out all the values for a given key. (Plus, perhaps have a
> 2-arg version which specifies a value to kill.)
> The tricky part is dealing with .size and the iterator methods. You
> need .size to reflect the number of keys, not pairs, to be consistent
> with Map. But then .size doesn't match the length of the iterators
> returned by .items() or .values(), unless both of these are changed to
> only return the first value by default. (They can't return an array
> of values, because that's not what Map does.)
This is all very tricky and you may be able to make it work. But why?
Do you anticipate passing a multimap into a place that expects a map?
For these use cases, do you expect that the passer of the multimap
reliably intends to effectively pass only these "first" mappings per
key to the receiver? As I write this, it all seems crazy and
unreliable, and not a pattern we should encourage. Let's keep Map and
MultiMap as distinct types, and standardize only Map, WeakMap, and Set
>> Since Map and Set will be in ES6 and MultiMap is trivially
>> implementable from these, we can wait until we see some experimental
>> implementations before standardizing. Hence the ES7 target.
> Sure. It just means that we'll have legacy in the DOM already as well.
>> The issue of subclassing built-in types in general is interesting and
>> important. Whatever we do for this in general, we should not need to
>> make any special case for Map and MultiMap. In general, new built-in
>> abstractions should act as much possible as if they were implemented
>> by an ES6 class and exported by an ES6 module. (Likewise for old
>> build-in abstractions, but less will likely be possible for these.)
More information about the es-discuss