I noted some open issues on "Classes with Trait Composition"

Bob Nystrom rnystrom at google.com
Thu May 19 18:03:24 PDT 2011

On Thu, May 19, 2011 at 5:20 PM, Brendan Eich <brendan at mozilla.com> wrote:

> Taken together, I wonder whether we aren't abusing *Declaration* to bind
> properties.

+1. I've been mostly working at this informally and haven't spent much time
looking at the EBNF yet, but I'd expect a class body to have its own set of
productions just for the small set of members you can define in a class
(fields, getters, setters, methods, constants). We may want to expand that a
bit (nested classes?), but I like the idea of it being its own set of
declaration forms and not just "every declaration ES allows elsewhere".

Also, are nested classes best bound to prototype properties? class A { class
> B {} ... }; a = new A; b = new a.B; ... is consistent along one dimension
> but it expresses something super-rare in the prototypal pattern used today,
> in my view unheard of.

This is a deeply fishy corner case. If you did:

class Outer {
  class Inner {}

then the proposal implies Inner would indeed be a property on
Outer.prototype, but my strong hunch is users would expect that to be on the
ctor (Outer.Inner). To get that, you have to do:

class Outer {
  static class Inner {}

An alternative to property initialisers only, one Dave and I misunderstood
> the strawman to be proposing: declarations, as opposed to initialisers,
> bound temporaries once in the lexical scope of the class body, for use by
> methods and other nested forms. In other words, implicitly private class
> static bindings. Was this considered?

Mark's original proposal treated a class body like a regular lexical scope,
which implies having local variables in it. I think the trouble was that it
also implied allowing any arbitrary statement inside the class body, and
that makes it really hard to have a nice syntax for member declarations
(which are what the majority of a class body is). Allowing any statement in
there stomps over so much syntactic space that there isn't a lot left for
what we care about.

So the consensus we came up with was that a class body isn't a lexical scope
and only allows member definitions. That makes it easy to have a nice syntax
for those, and gives us breathing room in the future for adding new stuff to
classes (like mixins). If you want a lexical scope your class members can
access, you can just nest the whole class definition:

let MyClass;
  let superSecret = 'shhh!';

  MyClass = class {
    isSecret(maybe) {
      return maybe == superSecret;

(There's probably a less awkward way to do that, but you get the idea.)

> As a ClassElement, "x = y;" is just shorthand for "let x = y;". Likewise
> "static x = y;" is just shorthand for "static let x = y;".
> Except let binds lexically in other declarations. This seems an
> aesthetic/philosophical objection -- we can make let mean what we like in
> class body context -- but it also smells bad to me. You?

Given the choice between let and var for this, I'd lean towards var (or a
new keyword entirely), but I could probably be convinced either way.

- bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110519/6bffe046/attachment-0001.html>

More information about the es-discuss mailing list