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

Mark S. Miller erights at google.com
Thu May 19 16:24:02 PDT 2011


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

> On May 19, 2011, at 3:43 PM, Mark S. Miller wrote:
>
> Or if you have a measured need based on some existing code, which I'd love
>> to hear about: consider a prefixing keyword to make this look like an
>> alternative to static x = 0.
>>
>
> Bob initially used "var" for that purpose. I do not object to having such a
> short prefixing keyword. But ever since the "let is the new var" revolution,
> whenever my eye notices a "var", my immediate reaction is "Danger danger
> warning warning. Once we can, figure out what this code is doing and rewrite
> as using 'let' or 'const'." Once ES-next is real and people really can get
> rid of "var"s, I hope this reaction will become more common. Looking for bad
> old code to fix? Grep for "var". Anything that habituates us to "var",
> reducing this alarm reaction, seems bad.
>
>
> I note that *Declaration* is produced by *ExportableDefinition *produced
> by *PublicPrototypePropertyDefinition*. That means let, const, function,
> and nested class are all possible in a class body.
>

Yes.



>
>
> http://wiki.ecmascript.org/doku.php?id=strawman:classes_with_trait_composition#member_declarations_and_definitionsis light on details, but I took these to define local bindings usable in
> other *ClassElements* -- not to create prototype properties (or any kind
> of property on an object).
>
> Did I miss something?
>

Yes. An unannotated *Declaration* defines a prototype property of that
name.

    class Point {
      const x = 0;
      //...
    }

defines a non-writable, enumerable, non-configurable "x" property on
Point.prototype, as if by

    Object.defineProperty(Point.prototype, 'x', {
      value: 0, writable: false, enumerable: true, configurable: false
    });




>
>
> That said, if we decide we really want a keyword here and can't come up
> with a better alternative than "var", I probably could be talked into it.
> And I'm happy to see this added as an option to the strawman.
>
>
> I'm still not sure we need to bind (enumerable by default, I just noticed
> -- a for-in hazard) data properties on the class prototype.
>

I agree that data on the prototype is comparatively rare. But symmetry and
consistency sometimes lead us to supporting rare cases, merely to avoid
introducing special cases that prohibit them.



> If we do, I agree that var is not a good keyword to retask. We could make
> new keywords in context in the class body, I think. Dave mooted proto when
> we were talking about this. Just an idea.
>

I prefer "proto" to "var", so I could probably be talked into that as well.



>
>
> When I first saw this use of "class" I loved it. I never liked "static" and
> I disliked it even more after that. But the following syntactic case
> convinced me otherwise:
>
>     class A {
>       class B {...}        // defines A.prototype.B as a class
>       class class C {...}  // defines A.C as a class
>       class D() {...}      // defines A.D as a function.
>     }
>
>
> Oh, so nested class declaration binds a prototype property? That is
> confusing. What do let, const, and function do?
>

The same thing. An unprefixed let defines a writable enumerable configurable
property on the prototype. An unprefixed const as above defines a
non-writable, enumerable, non-configurable property on the prototype. An
unprefixed class or function defines a non-enumerable ...

All of these, as well as the other ExportableDefinitions, define
corresponding props on the constructor when prefixed by something --
currently "static".



> The other ClassElement production right-hand sides produce accessor and the
> new method property initialiser forms, not *Declarations*.
>

As a ClassElement, "x = y;" is just shorthand for "let x = y;". Likewise
"static x = y;" is just shorthand for "static let x = y;".



>
>
> by contrast, I don't think the following creates any similar confusion
>
>     class A {
>       class B {...}        // defines A.prototype.B as a class
>       static class C {...} // defines A.C as a class
>       static D() {...}     // defines A.D as a function.
>     }
>
>
> Given a nested class declaration binding a prototype property, I see your
> point. But is that nested class semantic really the right one, and how does
> it related to the other *Declaration* variants?
>

Symmetric and consistent without special cases.

Also, Gilad Bracha has shown many cool patterns in Newspeak leveraging the
ability to inherit a default nested class but being able to override it by a
like-named nested class in a subclass. Once you get used to it, it's
actually much more natural and expressive than static nested classes.


>
> /be
>
>


-- 
    Cheers,
    --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110519/f4207a8f/attachment-0001.html>


More information about the es-discuss mailing list