shortcuts for defining block-local private names, plays nicely with @foo syntax

Allen Wirfs-Brock allen at wirfs-brock.com
Sun Jan 22 16:31:58 PST 2012


On Jan 21, 2012, at 12:07 PM, Brendan Eich wrote:

> This was already proposed. See the whole strawman, but in particular these sections:
> 
> http://wiki.ecmascript.org/doku.php?id=strawman:private_names#the_private_declaration
> http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declaration_scoping
> http://wiki.ecmascript.org/doku.php?id=strawman:private_names#private_declarations_exist_in_a_separate_name_space_parallel_to_the_variable_binding_environment
> 
> The last really was too much for some folks. It makes the meaning of an identifier after . or before : in an object literal depend on a binding declaration, possibly far above.
> 
> We could revive this, but deferring it and simplifying led to
> 
> http://wiki.ecmascript.org/doku.php?id=harmony:private_name_objects
> 
> which is in ES6.
> 

There has also been a number of discussion threads here about syntax for private name access.

I personally have come to the conclusions that

   obj. at foo

would be a better than 

   obj[foo]

for accessing a property of obj that is keyed by the private name that is the value of the foo binding.

My impression, is that a number of other participants in these discussion share this opinion.  These are various reasons for  this preference, including pleasantness, experience from CoffeeScript and a desire (rationalize in http://wiki.ecmascript.org/doku.php?id=strawman:object_model_reformation ) to strongly distinguish routine structural property access from dynamically computed data key accesses.

The plan of record is that ES6 will support the creation of private named properties in object literals using syntax like this:

const foo = name.create();
let obj = {
   [foo]: 42
};

However, if @foo is going to be used for private named member accesses instead of [foo] then it also makes sense to use @ instead of [ ] in object literal property definitions. In that case, we should replace the above with:

const foo = name.create();
let obj = {
   @foo: 42
};

Note that this doesn't run into any of the scoping or multiple name space issues that were raised as objections to the original private name proposals liked above.  Also it doesn't preclude use of [ ] to access private names. You could still say either
   obj[foo] or obj. at foo to access the properties whose key is the value of foo

 I plan on proposing at the next TC39 meeting that we support .@ member accesses and that we replace the use of [expr ] to define private named properties in object literals ( http://wiki.ecmascript.org/doku.php?id=harmony:object_literals#object_literal_computed_property_keys ) with @identifier to define such properties.

Regardless of whether this proposal flies we could consider supporting:

private foo,bar;

as a short hand for:

//assume already done: import name as "@names";  
const foo=name.create(), bar=name.create();

I think this would be a desirable addition, but I don't want it to be a make or break issue for the .@ proposal.

There are a couple of decision that still need to make for this proposal:

1) should .@ member access and @ object literal property definitions permit he property key to be any toString-able value and not just private name values?  The current plan of record does not require a private name value in the analogous contexts.
I'm slightly inclined towards requiring private name values, but would be happy either way.

2)  elimination of arbitrary expression as direct keys in object literal property definitions:

The current "computed property keys" proposals allows things like:

for (var n=0;n<10;) {
   a.push( {
      ["prop"+n]: n++
   });
}

Do we really need to support this sort of computed property name definition?  If so, we could probably allow something such as:

for (var n=0;n<10;) {
   a.push( {
     @("prop"+n): n++
   });
}

I'm include to not supporting the such arbitrary expressions in such property definitions, particularly if 1) above is decided as no.  Then this could be expressed as

for (var n=0;n<10;) {
   let k = "prop"+n;
   a.push( {
     @k: n++
   });
}

3) should @foo as a primary expression be interpreted as this. at foo

I think it should, but note that this means that 

const foo = name.create();
let obj = {
   @foo: @foo
};

would mean the same as:

const foo = name.create();
let obj = {
   @foo: this. at foo  /key and value probably different values
};

rather than:

const foo = name.create();
let obj = {
   @foo: foo  //key and value are the same value
};

This might be a source of confusion for some JS programmers.

Thoughts?

Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120122/08f7e810/attachment-0001.html>


More information about the es-discuss mailing list