names [Was: Approach of new Object methods in ES5]

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Fri Apr 16 14:05:28 PDT 2010


Hello David,

Friday, April 16, 2010, 10:31:07 PM, you wrote:

>> Name sounds like a stripped-down uninterned symbol (http://bit.ly/bY3Jkg) to me.

> Yup.

>> It's an object with a magic attribute that says, unlike any other object you might try to use it as a property name, it is not coerced into a string first.  And it is compared by identity when looked up.  And it is invisible to (all?) enumerations of property names.

> Yup again. Basically it entails a slight generalization of the
> property lookup semantics; instead of ToString there would be a
> ToPropertyName meta-operation, which for existing ES objects would
> just delegate to ToString, but for the new class of things would be the identity.

Still naming convention (the thing which ES doesn't use -- and in vain)
is a good and elegant approach. That is Python (or even Ruby)
uses.

JS already borrowed a lot from Python. So, its naming convention for
_private and __protected is a good approach. Although, maybe not in
such exact view (with leading underscore, but nevertheless).

As Brendan already mentioned, unfortunately, it's too late to talk
about naming conventions for this purpose because of backward
compatibilities. So the leading underscore doesn't fit.

But, there are many other interesting and elegant symbols.

Ruby e.g. uses leading colon for symbols - :symbol. But for JS it will
look a bit odd, because it already uses colon to separate property's value
from its:

var foo = {x: 10, :y: 20} // although...

where :y - is your "private" "Name" symbol.

Choose any:

{x: 10, _y: 20}, // habitual

{x: 10, -y: 20}, // interesting

{x: 10, !y: 20} // be careful, it's !private

(although, in Ruby exclamation mark is used for "dangerous" methods,
which modifies the argument instead of returning the new one)

{x: 10, .y: 20} // also interesting, like a "hidden file"

{x: 10, ~y: 20} // a bit ugly, but acceptable

{x: 10, <y>: 20} // to many different braces, doubtful.

and so on, there are many interesting naming conventions (which are
not yet "borrowed" by backward compatibility).

It looks a bit odd for e.g. Java programmers which used to write that
long-long lines, but -- it's just as a variant.

Although, the variant with the leading dot is interesting, but it will look odd using with the
corresponding property accessor:

let obj = {
  .foo: 42,
  getFoo: function () this..foo  // ? too odd
};

(Although, we have already such: 1..toString() -- "1" for fractional
part of numbers)

How naming convention will help? -- in any position in code we can
presiseally say what access level this property has. We do not need
some special keywords.

But, that's just abstract suggestion. Which at current step (and
moment) incomparable with the JS nature.

Meanwhile, the "classical" approach for access levels is also elegant.

Leaving naming conventions (if you will) it is also possible to use
this "private" keyword in this form:

Declarative:

let obj = {

  private:
    foo: 42,
    bar: 41

  public:
    baz: 43
    getFoo: lambda() this.baz + this.bar;

};

obj.foo; // undefined
obj.bar; // undefined

obj.baz; // 43
obj.getFoo(); // 83

obj.bar = 44; // Error, "bar" is private ?

where "private:" keyword with the colon will fill "obj" with "Name"
symbols followed by it; "public:" then is just to separate the section. Actually,
this quit standard approach. Of course, lexer/parser rules should be
changed and "private" and "protected" then cannot be used as normal
property names (which ES5 seems allows, e.g. this.super()).

Special "Name" constructor for this aim seems superfluous. There
should be the way to create them fast and elegant (and with minumum,
but still elegant of code). Although, name Symbol" for this
constructor is acceptable.

Imperative:

obj[private: "x" + dynamicName] = 100;

obj.private: x = 100;

obj[new Symbol("x")] = 100;
obj[Symbol("x")] = 100;

// or again naming convention
obj[.x] = 100;

trusted(obj, .x);
trusted(obj, private:x);
trusted(obj, Symbol("x")); // odd

// with intermediate action
let x = new Symbol;
trusted(obj, x);

Also -- just a variant of suggestion. But it souldn't be too complex
with several intermediate actions.


P.S.: by the way, having in Rhino access to the activation object, it
is possible to manage objects increasing encapsulation providing
higher abstraction -- and again -- with using leading underscore
convention: http://gist.github.com/363056 So from this viewpoint -- it
is also pity that spec officaly doesn't allow to get access to the AO
(activation object) -- it could make a good metaprogrammig solutions,
as locals() or vars() in Python. E.g. in this example I can use only
function declaration forms and omit "this." prefix each time.

But, JS of course isnt' a Python, although it's very similar,
JS has it's onw ideology.

Dmitry.



More information about the es-discuss mailing list