new strawman: syntactic support for private names

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Aug 31 10:39:39 PDT 2012


On Aug 31, 2012, at 12:53 AM, Andreas Rossberg wrote:

> On 29 August 2012 18:39, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>> There are been various previous runs at defining syntactic support for using
>> unique/private names.  They all run into either real or hypothetical
>> usability issues that blocked adoption. One consistent area of concern has
>> been contextual variation in the use of a sigil such as @.  For example:
>> 
>> private member;  //(no sigil) user just wants to think of "member" as a
>> restricted visibility property key.
>> let obj = {@member: 42};     //they have to remember to use the sigil here
>> because this is a context where identifiers are implicitly quoted
>> let fortytwo = obj[member];  //must not use the sigil here
>> alert(obj. at member);           //need to remember to use the sigil here ,
>> obj.member would meaning something completely different.
>> 
>> In the above scheme, there is nothing that syntactically identifiers a bound
>> name that is intended to use as a restricted property key.  The sigil is a
>> syntactic element of the usage context.  Some contexts require one, others
>> do not.  A user has to mentally track which identifiers hold property keys
>> and and remember in which contexts a sigil is required or must be avoided.
>> 
>> In my proposal, I attempt to simplify this by making the sigil part of the
>> actual identifier.  At the point of declaration, you decide that a certain
>> identifier is going to be used to represent a unique name property key. This
>> decision is reflected in the actual identifier because it must be prefixed
>> with the @.  It is also a immutable binding. It's value is guaranteed to be
>> name object that was originally associated with it. All subsequent uses of
>> the identifier must also be prefixed.  There is never any confusion about
>> where you are referring to name object based property name or to a string
>> property name. You don't have to remember which context are quoting and
>> which are not.
>> 
>> This seems simple, to me.
> 
> Two observations. First, IIUC, separate namespaces mean that I can _not_ write
> 
>  let foo = new Name
>  o. at foo = 1
> 
> anymore. For first-class names, I would have to fall back to
> 
>  o[foo] = 1

Yes, that is an intentional part of this design. The concept is that @names are similar in usage to immediate values, but ones that have to be explicitly introduced via a declaration.

> 
> Wouldn't that reintroduce the very problems we tried to avoid by
> considering . at foo as a syntax separate from [foo] in the first place,
> i.e. confusing named property access with indexing collections?

In my proposal . at foo isn't separate syntax.  It's a dot, followed by a @name.  A simplified version of the grammar as:

MemberExpression :
   ...
   MemberExpression [ Expression]
   MemberExpression . PropertySelector

PropertySelector :
   IdentifierName
   AtName

PrimaryExpression :
   ...
   AtName

So, there is technically no confusion between property access and indexing collection. Dot and Index access have distinct syntax and semantics.  The point of potential conceptual confusion is that AtName used as a PropertySelector and AtName used as a Primary expression evaluate in exactly the same way.  This is different from IdentifierName which has different evaluation rules for those two contexts.

We can't  treat At-Names in PropertySelector contexts  just like IdentifierNames, because in that case an expression like obj. at foo]  would means the same thing as obj["@foo"] which is not what we are trying to accomplish.  Note, that we would have similar behavior if we allowed string constants to appear immediately after a dot.  EG
   o."foo"
   o["foo"]

Basically, within the scope of a name/private declaration the best way to think about an AtName is as an immediate representation of its value rather than a variable reference. 

I agree this is anomalous, relative to the handling of IdentifierNames but there has to be a anomaly somewhere  if we are gong to allow dot property access using unique/private names.  In practice, I see little reason for anybody every wanting to say o[@foo] rather than o. at foo. So, I expect people will seldom encounter this anomaly.
 
> 
> Second, the proposal effectively destroys the first-class nature of
> @names, because you can only bind them fresh via special declarations,
> not to the result of some computation. That is, unless you also allow
> name alias declarations
> 
>  name @foo = expr
> 
> to recover the special syntactic status for a computation's result
> (i.e., the counterpart to allowing @foo as a free-standing
> expression). In other words, I think support for name alias
> declarations has to be an integral part of the proposal, not an
> optional one.

A agree that the initializer in name declaration is very useful and I wouldn't want to be adopted this proposal without it.

Allen


More information about the es-discuss mailing list