On Mon, Jul 18, 2011 at 9:09 PM, Brendan Eich <[email protected]> wrote:
> On Jul 18, 2011, at 9:02 PM, Rick Waldron wrote:
>
> Hey Bob, FWIW...
>
>
>> class Point {
>> constructor(x, y) {
>> this.x = x;
>> this.y = y;
>> }
>>
>> zero() {
>> return new Point(0, 0);
>> }
>>
>> unit() {
>> return new Point(1, 1);
>> }
>>
>> prototype {
>> manhattanDistance() {
>> return Math.abs(this.x) + Math.abs(this.y);
>> }
>> }
>> }
>>
>
> ...That's actually the nicest, most intuitively designed "class" structure
> I've seen so far.
>
>
> This is actually close to a less magical syntax that flips around the
> "ClassElements" (immediate children of the class {...} container) to specify
> class methods. Here's a less sugared version:
>
> class Point {
>> zero() {
>> return new Point(0, 0);
>> }
>>
>> unit() {
>> return new Point(1, 1);
>> }
>>
>> prototype: {
>> constructor(x, y) {
>> this.x = x;
>> this.y = y;
>> }
>>
>> manhattanDistance() {
>> return Math.abs(this.x) + Math.abs(this.y);
>> }
>> }
>> }
>>
>
>>
> Notice how constructor is in the prototype object, as in JS with
> constructors and prototypes. Also, prototype: {...} not prototype {...}.
>
> As Bob noted, though, even in JS and moreso (from Allen's stats) in
> Smalltalk, class methods are uncommon compared to prototype methods. Do you
> really want an extra level of indentation for the latter?
>
> This example is skewed away from norms by having two class methods to one
> prototype method. I think constructor was mislocated, and when I fixed it
> just above, the instance- vs. class-method counts matched. Still
> unrealistic, though.
>
> If we want *more* magic from the class syntax, not less, we could use 'new'
> at the outer class-element indentation level to declare the constructor, and
> automagically impute 'constructor' in the prototype from it. But we'd still
> be over-indenting the prototype methods, which are many, compared to the
> class methods (few).
>
This is probably a terrible idea, but in the interest of considering all
options, 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);
}
}
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);
}
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:.)
That solves the double indentation problem. 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;
// "private" before a section lets you declare private members on that
object.
private new:
health;
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>
- bob
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss