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

Tab Atkins Jr. jackalmage at gmail.com
Sun Jan 22 19:36:51 PST 2012


On Sun, Jan 22, 2012 at 4:31 PM, Allen Wirfs-Brock
<allen at wirfs-brock.com> wrote:
> 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.

I have a question, that may be an objection.  In my blog post
<http://www.xanthir.com/blog/b4FJ0>, I demonstrate several example
usages of Names.  Most of them involve using a Name that's hung off of
another object.  Is there a way to support this pattern without a
temporary variable?

For example, from my post:

myCoolObject.prototype[Iterator.getIterator] = function(){...}

Using @ for access, would
"myCoolObject.prototype. at Iterator.getIterator = function(){...}" work,
or would that attempt to retrieve a property using "Iterator" as a
Name, then retrieve the "getIterator" property of that?

If the latter, this is rather inconvenient for what I expect will be
common patterns.

> 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

Regardless of the answer above, this seems to allow the actual usage
in my post, which is nice.  But it appears that it will be impossible
to use the pattern I cite in an object literal without assigning it to
a temporary variable.  Is this correct?


> 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.

I don't understand what the use of a toString-able value would be in
the context of a private variable, since you can only store private
things with Names.


> 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++
>    });
> }

This seems related to my concern above, except that this example uses
string-valued variables rather than Names.


> 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.

I suspect that either would be confusing.  I agree with you that it's
better for @foo to be interpreted as this. at foo.

~TJ


More information about the es-discuss mailing list