On Nov 4, 2011, at 6:44 PM, Mark S. Miller wrote:

> 
> On Fri, Nov 4, 2011 at 10:37 AM, Axel Rauschmayer <a...@rauschma.de> wrote:
>> 
> 
> 
> As an aside: This problem would go away if we really did distinguish between 
> accessing a property and accessing a collection element. Then the former 
> would be done via Object.* methods, while the latter would be done via square 
> brackets.
> 
> I admit that I haven't followed the previous thread on ".[" and such. Is 
> there a short summary? I ask because my diagnosis is similar but my 
> conclusion is reversed. The lesson I take from this is not to use objects as 
> maps. It you want a map, create a Map() and say map.get(key) and map.set(key, 
> value) rather than using square brackets.
> 

My original proposal is at 
https://mail.mozilla.org/pipermail/es-discuss/2011-October/017468.html 

Here is an abridged version:

We then give MemberExpression [ Expression ] a new semantics.  Here is the 
initial skeleton of this new semantics:

    if MemberExpression is a "collection" return the result of invoking its 
"element getter/setter method"
    else do the algorithm from ES5 11.2.1

What this says is that for any existing ES5 style object continue to work just 
like they always have. But in ES.Harmony there would be a new kind of 
"collection" object for which .  works differently from [ ].

So to make the above skeleton semantics more meaningful we need to define what 
we really mean by "collection" and by "element getter/setter method".  Let's 
start with the latter.

Let assume that there are two predefined private name object values that are 
required to exist by the ES.Harmony spec. Let's refer to those values as 
@elementGetKey and @elementSetKey  (these are just names we use in the spec. 
language to talk about those private name values, the actual private name 
objects would be dynamically provided by ES implementations).  Then a "element 
getter/setter method" is simply an object property whose property key is either 
@elementGetKey or @elementSetKey.  The signature of these methods would 
normally be:
    function /*element getter */ (elementKey){return anElementValue};  
    function /*element setter */ (elementKey, newElementValue){};

Further more we define "collection" to mean an object that has a property that 
is a  "element getter/setter method".  The property may be either own or 
inherited.

How would we define such an "collection" object.  It could be as simply as 
something like this:

import {collectionGetter, collectionSetter} from "@metaCollections";

export function StringKeyedMap() {
   this.__content = Object.create(null);  //note __content object is a "normal 
object" and  [ ] on it does regular property access
   Object.defineProperty(this, collectionGetter,{value: function(k) {return 
this.__content[k]});
   Object.defineProperty(this, collectionSetter,{value: function(k,v) 
{this.__content[k]=v;});
   this.size = function() {Object.getOwnPropertyNames(this.__content ).length}; 
 //I'm lazy
   this.has = function(k) {return {}.hasOwnProperty.call(this.__content,k};
   this.delete = function(k) {return delete this.__content[k]}
}

This implements a string-keyed map with the same interface as used in the 
simple _map proposal, except that [ ] is used instead of get/set methods for 
element access. Note that there is no conflict between element names and method 
names such as "size" and "has".  It uses as backing store a regularly object 
that acts as an string-keyed hash table.

Using this techniques all sorts of "collection" classes could be build 
including array-like collections with domain restrictions of their element 
values. They would all be fully "subclassable".

Also, the length invariant semantics of built-in array objects can be emulated 
without having to use Proxies.


_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to