Class literals: does "public" still make sense?

Kam Kasravi kamkasravi at yahoo.com
Sun Sep 25 15:48:56 PDT 2011


Would the new private syntax then go from

(old syntax)
class Monster {
  // The contextual keyword "constructor" followed by an argument
  // list and a body defines the body of the class’s constructor
  // function. public and private declarations in the constructor
  // declare and initialize per-instance properties. Assignments
  // such as "this.foo = bar;" also set public properties.
  constructor(name, health) {
    public name = name;
    private health = health;
  }
 
  // An identifier followed by an argument list and body defines a
  // method. A “method” here is simply a function property on some
  // object.
  attack(target) {
    log('The monster attacks ' + target);
  }
 
  // The contextual keyword "get" followed by an identifier and
  // a curly body defines a getter in the same way that "get"
  // defines one in an object literal.
  get isAlive() {
    return private(this).health > 0;
  }
 
  // Likewise, "set" can be used to define setters.
  set health(value) {
    if (value < 0) {
      throw new Error('Health must be non-negative.')
    }
    private(this).health = value
  }
 
  // After a "public" modifier,
  // an identifier optionally followed by "=" and an expression
  // declares a prototype property and initializes it to the value
  // of that expression. 
  public numAttacks = 0;
 
  // After a "public" modifier,
  // the keyword "const" followed by an identifier and an
  // initializer declares a constant prototype property.
  public const attackMessage = 'The monster hits you!';
}

to:
class Monster {
  // The contextual keyword "constructor" followed by an argument
  // list and a body defines the body of the class’s constructor
  // function. public and private declarations in the constructor
  // declare and initialize per-instance properties. Assignments
  // such as "this.foo = bar;" also set public properties.
  constructor(name, healthvalue) {
    public name = name;
    module name from "@name";
    private health = name.create();
    this[health] = healthvalue;
  }
 
  // An identifier followed by an argument list and body defines a
  // method. A “method” here is simply a function property on some
  // object.
  attack(target) {
    log('The monster attacks ' + target);
  }
 
  // The contextual keyword "get" followed by an identifier and
  // a curly body defines a getter in the same way that "get"
  // defines one in an object literal.
  get isAlive() {
    return this[health] > 0;
  }
 
  // Likewise, "set" can be used to define setters.
  set health(value) {
    if (value < 0) {
      throw new Error('Health must be non-negative.')
    }
    this[health] = value
  }
 
  // After a "public" modifier,
  // an identifier optionally followed by "=" and an expression
  // declares a prototype property and initializes it to the value
  // of that expression. 
  public numAttacks = 0;
 
  // After a "public" modifier,
  // the keyword "const" followed by an identifier and an
  // initializer declares a constant prototype property.
  public const attackMessage = 'The monster hits you!';
}
?

If so it seems odd, privately named variables like health, although declared in the constructor are implicitly available throughout the class.


On Sep 25, 2011, at 2:08 PM, Brendan Eich <brendan at mozilla.com> wrote:

> On Sep 25, 2011, at 1:04 PM, Kam Kasravi wrote:
> 
>> If the intent of classes is to provide a declarative syntax for its 'shape' then dropping the private syntax in lieu of private name objects seems to run counter to this philosophy. 
> 
> We did not agree to drop the private declaration syntax at the July TC39 meeting. Perhaps my understanding of our agreement then does not match Marks?
> 
> What we agreed to drop was the private(this) straw syntax in the classes proposal, in favor of this[x], this[y], for private-declared private name objects x and y.
> 
> /be
> 
> 
>> As I understand it, private name objects are a runtime construct dependent on the '@name' module and thus have no declarative definition. 
>> Are there yet to be defined ways to declaratively define/discover an instances private namespace?
>> 
>> From: Axel Rauschmayer <axel at rauschma.de>
>> To: Mark S. Miller <erights at google.com>
>> Cc: es-discuss <es-discuss at mozilla.org>
>> Sent: Sunday, September 25, 2011 8:59 AM
>> Subject: Re: Class literals: does "public" still make sense?
>> 
>> Static analysis of the constructor should be able to do most of what "public" does, but after consulting the spec again, I see its advantages:
>> - Const classes make public properties unconfigurable and read-only.
>> - Shouldn’t public properties in non-const classes be unconfigurable, too? Are such properties expected to be configured? Read-only properties could be created via "public const".
>> 
>> On Sep 25, 2011, at 4:09 , Mark S. Miller wrote:
>> 
>>> Hi Axel,
>>> 
>>> This was one of the options we considered. At one point it was the main class proposal. The problem is that since it looks exactly like an imperative assignment to a property of "this", it should have the semantics of an imperative assignment to a property of "this". In fact, the current class proposal does not disallow it, and gives it exactly these semantics.
>>> 
>>> However, when used as the only or main means of initializing an instance, it defeats one of the main purpose of classes: The shape of the instances of a given class are no longer a static declarative feature of the class itself. Again, the contrast with modules is instructive. A CommonJS module exports only by imperative assignment to properties of an "exports" object. A proposed ES-next module exports by annotating top level declarations with "export". As an abstraction mechanism, it would be bizarre to have good abstraction properties only for abstractions that cannot be multiply instantiated.
>>> 
>>> 
>>> On Sat, Sep 24, 2011 at 4:17 PM, Axel Rauschmayer <axel at rauschma.de> wrote:
>>> Without private members, do we still need the keyword "public" in class literals?
>>> 
>>> For example, instead of
>>>  constructor(geometry, materials) {
>>>    super(geometry, materials);
>>> 
>>>    public identityMatrix = new THREE.Matrix4();
>>>    public bones = [];
>>>    public boneMatrices = [];
>>>    ...
>>>  }
>>> I find the following just as intuitive, without the need for the keyword "public":
>>>  constructor(geometry, materials) {
>>>    super(geometry, materials);
>>> 
>>>    this.identityMatrix = new THREE.Matrix4();
>>>    this.bones = [];
>>>    this.boneMatrices = [];
>>>    ...
>>>  }
>>> 
>>> Similarly intuitive is something that I’ve seen somewhere – passing through constructor arguments as members.
>>>  class Point {
>>>    constructor(this.x, this.y) {
>>>    }
>>>  }
>>> 
>>> I don’t think "public" helps, I think it makes things *less* intuitive.
>>> 
>>> --
>>> Dr. Axel Rauschmayer
>>> 
>>> axel at rauschma.de
>>> twitter.com/rauschma
>>> 
>>> home: rauschma.de
>>> blog: 2ality.com
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>> 
>>> 
>>> 
>>> -- 
>>>     Cheers,
>>>     --MarkM
>> 
>> -- 
>> Dr. Axel Rauschmayer
>> 
>> axel at rauschma.de
>> twitter.com/rauschma
>> 
>> home: rauschma.de
>> blog: 2ality.com
>> 
>> 
>> 
>> 
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>> 
>> 
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110925/31835523/attachment-0001.html>


More information about the es-discuss mailing list