On May 21, 2013, at 6:42 PM, Tab Atkins Jr. wrote:

> On Tue, May 21, 2013 at 4:19 AM, Brendan Eich <[email protected]> wrote:
>> David Bruant wrote:
>>> This description ("arbitrary string keys", "bidirectional link with style
>>> rule") suggests that you want a proxy (canonical values are in the style
>>> rule, the proxy is just a façade with a bit of validation/coercion logic).
>>> That's the sort of use case they've been introduced for.
>> 
>> I don't see why a proxy is required if the API is get/set/has (like Map's).
>> We're not making properties appear without knowing their names, so this is
>> not a proxy use-case on its face.
>> 
>> Of course, coercing key type makes the API not Map. So if the
>> bi-directionality is important, this would be a custom Map-like class.
>> 
>> So Tab: why do you want to abuse Map instead of make a custom class?
> 
> Restating from my earlier post:
> 
> 1. when someone asks "is this Map-like?" in an appropriately idiomatic
> JS way, they get a "yes" answer.

First you have to define what "Map-like" means.  Is it supporting get/set/has?  
Is it any object that conforms to Sam's "check" invariant?  

There is currently no specified way to ask if something is "Map-like" because 
we don't know.  BTW, in the school of dynamic language OO development that I 
come from it is considered an "anti-pattern" to ask if something is "a Foo" or 
is "Foo-like".  If your (informal) contract says that you require that somebody 
pass you a Foo-like object, just assume that they did.  If they don't some sort 
of error is likely to occur soon enough.  You have to bake sure that you 
actively mantain essential internal invariants but there is no real need to 
sweat about higher-level "type check" around the edges.

In the ES6 built-ins where there is a need to do a quick behavoral check for a 
"kind" of object we defined a method such as @@isRegExp which is used to enable 
various string methods to recognize multiple different concrete implementations 
of "RegExp-like" objects.  You could imagine us providing a@@isMap but we 
currently have no strong use cases for it.

> 2. when someone adds a new function to Maps in an appropriately
> idiomatic JS way, the method also applies to this object

You mean add methods to Map.prototype?  Modify other people's (including 
built-in) prototypes is rather frowned upon.  Map is designed to be subclassed. 
 If you what a new kind of map with additional methods the appropriate way to 
do that would be to add those methods of a subclass and use instances of the 
subclass instead of Map.

> 3. when JS expands the set of built-in methods for Map, it also gets
> applied to this object without me having to update my spec.

Why do you think this will happen?  First let mean define what "generic map 
method" would mean to mean.  It is a method that does not directly depend upon 
the internal [[MapData]] state.  It only accesses that state indirectly via 
get/set/has etc.

Currently there are no generic Map.prototype methods.  They all are directly 
tied to the [[MapData]] representation for some specific reason. 

At this point in time it isn't obvious what generic map methods would be useful 
to add in the future.

> 4. for all the existing Map methods, I get identical/equivalent methods
> without having to manually redefine every single one of them

Except that all of the existing methods are dependent upon the specific 
[[MapData]] representation. If you want to use a different representation of 
the data for a new kind of map you are going to have to over-ride all of the 
existing methods anyway.

You could define Map using a two level implementation strategy where, for 
example, the "get" method called perhaps an @@get method and where all 
representational knowledge would be in the @@ methods.  However, you you still 
have to over-ride the same number of @@ methods so I don't see a major gain in 
that approach.

> 
> All of these follow from the basic statement that *this is a map*,
> because it clearly is.  It's limited to string keys and values, but
> that's just some coercion rules.  Every single operation defined on
> Maps currently is meaningful and useful for this object, and virtually
> any method you can imagine adding to Maps in the future is also
> meaningful and useful.
> 
> Ducktyping this as a Map is terrible, because it breaks #2/3/4, and
> arguably #1 depending on what you consider an "appropriately
> idiomatic" way of asking if something is Map-like.
> 
> Just subclassing Maps and providing my own get/set functions is not as
> terrible, but still bad for a few reasons: I need to study the ES spec
> very carefully to figure out which operations are "basic" (interact
> directly with [[MapData]] rather than going through existing
> operations) and redefine all of them, and anyone who ever does
> something like Map.prototype.set.call(myObj, ...) will break the
> invariants I need maintained, with mysterious and undefined results.

There are none.  All the current Map methods are intentionally dependent upon 
[[MapData]]

> 
> This should be super-simple - I just want to supply a custom object as
> the [[MapData]] which can intercept sets so it can coerce the values
> beforehand.  In every other way, this is a Map.

Note [[MapData]] isn't just a specification abstraction over a data store.  It 
also abstracts all the access patterns of that data store.

Allen


_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to