On Thu, Sep 29, 2011 at 6:20 PM, Brendan Eich <bren...@mozilla.com> wrote:

> On Sep 30, 2011, at 1:11 AM, Erik Arvidsson wrote:
>
> On Thu, Sep 29, 2011 at 17:08, Bob Nystrom <rnyst...@google.com> wrote:
>
> class Monster {
>
>   constructor(this.name, this.health) {}
>
>
> I <3 this. It beats the (public name, public health) variant in my view by
> being explicit and not dragging in p-words.
>

Yeah, me too. The big win for me here is that I find this confusing:

class Point {
  constructor(public x, public y) {
    x = 2; // is this valid? does it assign to this.x or just the local
argument variable?
  }
}

Using this.x in the constructor parameter list maintains a consistent
"always use this. to assign to object properties", which I like.


> This is great, and I'm still a sections fan, but they mix badly if there
> are any hints or smells of object literal data property initialiser synax.
>

Right. Personally, I'm not a fan of mixing object literal style into classes
(though I see the appeal from a unification perspective). Maybe that's just
my long C++/C#/Java habits.


> You (Bob) dodge that by using let, Oliver used var (and IIRC Bob started
> with var; so did ES4)
>

Yup. I actually prefer "var" slightly though I understand it gives Mark
hives (and for good reason). I don't really have much of a keyword
preference here at all as long as it's really short. Could be "thing" for
all I care. :)

-- however, Oliver and ES4 by fiat put data properties on the instance,
> methods on the prototype.
>

That feels a little... non-orthogonal? to me. Inside a class when you're
defining some property, there's two things you need to specify:

1. What flavor of property it is: function, constant, field, etc.
2. What object it gets defined on: constructor, prototype, instance.

Mixing those together so that 1 determines 2 feels kind of arbitrary and not
as flexible. I like the idea of the grammar informing one and sections
informing 2. Maybe that's just me.


> Separately, and a while ago, Alex pointed out that mutable prototype data
> properties, e..g let attackers = []; in this Monster example, are a footgun.
> People fail to shadow and mutate a shared singleton.
>

Yeah, I worry about that too, though I'm leery of giving up generality to
dodge that. (People complain as it is that class syntax is too rigid.)


> So why do we need declarative syntax for data properties on the prototype
> at all? Data properties on prototypes are exceedingly rare and usually a
> bug.
>

We want a syntax for properties on the constructor, so is it worth it to
specifically forbid that notation outside of the class: section?

If we *did* want to go down the path of a more rigid class pattern (i.e. no
data props on prototype, etc.) then I think we could support all of the
combinations we care about with a pretty terse notation:

class Point extends SomeBaseClass {
  // Constructor.
  constructor(this.x, this.y) {
    class.lastPoint = this;
  }

  // Constant on class.
  const ZERO = new Point(0, 0);

  // Data property on class.
  var lastPoint = undefined; // or let

  // Function on class.
  class add(a, b) {
    return a.add(b);
  }

  // Nested class (data property on class whose value is a class).
  class Foo {
    ...
  }

  // Constant on prototype: not supported
  // Data property on prototype: not supported

  // Function on prototype.
  add(other) {
    return new Point(this.x + other.x, this.y + other.y);
  }
}

This gets rid of sections, and gets rid of "static" by using "class"
instead. It avoids the "class class" problem for nested classes by declaring
by fiat that a nested class goes on the constructor.

Thoughts?

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

Reply via email to