Re: [Bug 20019] Support subclassing ES6 Map

On Tue, Nov 20, 2012 at 12:30 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> On Tue, Nov 20, 2012 at 10:57 AM, Mark S. Miller <erights@google.com> wrote:
>> [+es-discuss]
>>
>> 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
this round.



>
>> 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.)
>
> Agreed.
>
> ~TJ



--
    Cheers,
    --MarkM

Received on Tuesday, 20 November 2012 21:06:56 UTC