On Jul 19, 2011, at 11:07 AM, Bob Nystrom wrote:

> This is probably a terrible idea, but in the interest of considering all 
> options,

Not terrible at all, and thanks for considering more options. I claim that is 
what es-discuss is for, so long as you've thought out the pitch and checked to 
avoid rehashing.


> we could do something like:
>  
> class Point {
>   constructor(x, y) {
>     this.x = x;
>     this.y = y;
>   }
> 
> class:
>   zero() {
>     return new Point(0, 0);
>   }
> 
>   unit() {
>     return new Point(1, 1);
>   }
> 
> prototype:
>   manhattanDistance() {
>     return Math.abs(this.x) + Math.abs(this.y);
>   }
> }

I'm used to C++, so I buy it. Also, and more important, it avoids the 
gratuitous over-indentation tax on either class or prototype elements.


> So, class: and prototype: indicate that members declared after them go into 
> those objects, much like public: and private: in a class in C++. By default, 
> it assumes prototype: since that's where most members go. In this example 
> here, I'm switching back and forth just to show the idea, but idiomatic code 
> would likely be:
> 
> class Point {
>   constructor(x, y) {
>     this.x = x;
>     this.y = y;
>   }
> 
>   manhattanDistance() {
>     return Math.abs(this.x) + Math.abs(this.y);
>   }

Right, default is prototype: to match the predominance of prototype "instance" 
methods over class methods.


> class:
>   zero() {
>     return new Point(0, 0);
>   }
> 
>   unit() {
>     return new Point(1, 1);
>   }
> }
> 
> (It may be that we should use constructor: or static: instead of class:.)

Those hurt more. I like class, it is shortest and closest to the keyword that 
introduces the binding (in the named form, not for class expressions -- but 
those want a connection back to the keyword too).


> That solves the double indentation problem.

Right!


> We could possibly extend this to handle declaratively specifying instance 
> members and/or public/private too:
> 
> class Monster {
>   constructor(name, health) {
>     this.name = name;
>     this.health = health;
>   }
>  
>   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
>   }
> 
> // "new" lets you declare members on new instances. these would presumably be
> // invoked on the new object before the constructor body is run.
> new:
>   numAttacks = 0;
>   // declaring an instance property here mainly so you can document it. could 
> be
>   // useful later for guards or other annotations.
>   name;

Neat idea, although the assignment expression-statement appearance still 
rankles. It looks like statements are allowed there, rather than declaration 
forms of some sort. OTOH we are talking about properties, and declarations are 
in ES.next lexical binding forms if you exclude object literal property 
assignments from "declarations".


> // "private" before a section lets you declare private members on that object.
> private new:
>   health;

Not sure we need 'new' there given lack of private prototype properties in the 
proposal. It's a bit verbose. Probably even if we add private prototype 
properties we can let private: (in this idea you've pitched) default to private 
instance.


> class:
>   create(name) {
>     let health = Math.random(5, 20);
>     return new Monster(name, health);
>   }
>  
>   const attackMessage = 'The monster hits you!';
> }
> 
> Strangely, I don't find myself hating this as much as I expected. <shrug>

No, don't <shrug>, <cheer>. I think what you've suggested here is strictly 
better than (a) over-indenting one or another group of elements; (b) putting 
"instance variable" declarations in magic syntax in the constructor body; (c) 
festooning one's class declaration with repeated "static" prefix keywords.

I think this wins, so far. This does suggest we rushed classes in prematurely. 
I'm not saying anything more than that we should take our time and avoid 
marrying the syntax in the proposal. We already have agreed that private(this), 
private(foo), etc. is straw to burn up.

/be
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to