Class declarations

# Axel Rauschmayer (14 years ago)

Can we make progress on the class declaration front (important for usability and tool support)?

What is the current state with regard to the objections against an Ashkenas-style (or Herman-style) minimal solution (that is: mostly object initializer syntax, prefixed by the keyword class)? Unless the nature of classes will radically change in the future, I don’t see why we can’t start small and enhance in the future.

# Herby Vojčík (14 years ago)

Axel Rauschmayer wrote:

Can we make progress on the class declaration front (important for usability and tool support)?

What is the current state with regard to the objections against an Ashkenas-style (or Herman-style) minimal solution (that is: mostly object initializer syntax, prefixed by the keyword class)? Unless

From my point, the only big (but really big) problem is the word mostly. If classes would introduce special beast of their own, I will see them as a problem. If they could be built by reusing object-literal syntax, I'd gladly accept them.

the nature of classes will radically change in the future, I don’t see why we can’t start small and enhance in the future.

I would be glad to see some gallery of minimal approaches, with easy diffing showing the same code implemented in them (I would also propose minimal classes of my own). But it is reasonable only when minimal classes in general would be accepted as the way to go.

# Axel Rauschmayer (14 years ago)

I would be glad to see some gallery of minimal approaches, with easy diffing showing the same code implemented in them (I would also propose minimal classes of my own). But it is reasonable only when minimal classes in general would be accepted as the way to go.

Exactly! Otherwise, we’ll just go in circles.

# Brendan Eich (14 years ago)

Axel Rauschmayer wrote:

I would be glad to see some gallery of minimal approaches, with easy diffing showing the same code implemented in them (I would also propose minimal classes of my own). But it is reasonable only when minimal classes in general would be accepted as the way to go.

Exactly! Otherwise, we’ll just go in circles.

Not hermeneutic spirals, just circles. Feels like the last year (we cut off ES6 proposals, modulo exceptions/tweaks, last May; we had a big-ish classes strawman synthesized from several prior proposals; we lost Bob Nystrom to Dart).

Minimal classes had a good subset of TC39 supporting last summer in Redmond, but we got hung up future-proofing use-before-initialization for const and guards, if I recall correctly. The notes from the July meeting should cover this.

If we can fight the future in the future and start small, we may yet rescue classes.

I noted to Jeremy that even his classes gist snuck in a novelty or two (the one I remember is class <expr> evaluating <expr> and copying it

somehow). We need to avoid novelty, while accepting that doing so is to some extent future-hostile because present-friendly.

# Herby Vojčík (14 years ago)

Brendan Eich wrote:

I noted to Jeremy that even his classes gist snuck in a novelty or two (the one I remember is class <expr> evaluating <expr> and copying it somehow). We need to avoid novelty, while accepting that doing so is to some extent future-hostile because present-friendly.

Could you please make this clearer, if you can? I do not understand it fully, but what I understood so far (maybe mistakenly), I am afraid of.

You say no brand new idea has chance to get in, since it is not known what it brings in the future? I am kind of person that believes in crazy (read: really different) ideas can push things through... but nevertheless, what did you mean more exactly by this paragraph?

/be

Thanks,

# Brendan Eich (14 years ago)

Herby Vojčík wrote:

Brendan Eich wrote:

I noted to Jeremy that even his classes gist snuck in a novelty or two (the one I remember is class <expr> evaluating <expr> and copying it somehow). We need to avoid novelty, while accepting that doing so is to some extent future-hostile because present-friendly.

Could you please make this clearer, if you can? I do not understand it fully, but what I understood so far (maybe mistakenly), I am afraid of.

See gist.github.com/1329619 lines 59-73.

You say no brand new idea has chance to get in, since it is not known what it brings in the future? I am kind of person that believes in crazy (read: really different) ideas can push things through... but nevertheless, what did you mean more exactly by this paragraph?

Classes "as sugar" were first proposed at the "Harmony" meeting in Oslo, July 2008:

esdiscuss/2008-August/003400

Desugaring to existing JS syntax and semantics is good, it ensures library interop and eases compilation (trans-compilation), it avoids risk taken on in inventing new kernel semantics (we are way past the cut-off point for ES6). Successful language designers are conservative even when making radical founding design decisions.

We could certainly add a great many novelties to classes: use-before-definition errors for instance variables, separate instance variables distinct from properties, etc. etc. TC39 prefers to avoid such innovations. This doesn't mean we won't in due course add any such thing but we won't do it in a big bad "scenario-solving" rush for classes.

# Axel Rauschmayer (14 years ago)

See gist.github.com/1329619 lines 59-73.

Take away the idea of class as an operator (honest question: is programmatic construction of classes a use case that matters?) and it’s a very convincing minimal proposal. Then you have the option of adding support for private name objects and for constructor properties (via sections in the class declaration body and via Allen’s @ notation).

You say no brand new idea has chance to get in, since it is not known what it brings in the future? I am kind of person that believes in crazy (read: really different) ideas can push things through... but nevertheless, what did you mean more exactly by this paragraph?

Classes "as sugar" were first proposed at the "Harmony" meeting in Oslo, July 2008:

esdiscuss/2008-August/003400

Desugaring to existing JS syntax and semantics is good, it ensures library interop and eases compilation (trans-compilation), it avoids risk taken on in inventing new kernel semantics (we are way past the cut-off point for ES6). Successful language designers are conservative even when making radical founding design decisions.

We could certainly add a great many novelties to classes: use-before-definition errors for instance variables, separate instance variables distinct from properties, etc. etc. TC39 prefers to avoid such innovations. This doesn't mean we won't in due course add any such thing but we won't do it in a big bad "scenario-solving" rush for classes.

That seems like the right call. If anything, I would like to have support for classes that produce read-only instances and sealed instances (it’s still easy to accidentally add properties to an object) – both of which are tricky if subtyping is involved. I don’t see use-before-definition as too problematic, but there might be factors that I’m not aware of.

# Brendan Eich (14 years ago)

Axel Rauschmayer wrote:

We could certainly add a great many novelties to classes: use-before-definition errors for instance variables, separate instance variables distinct from properties, etc. etc.

protected as well as private names, another novelty.

TC39 prefers to avoid such innovations. This doesn't mean we won't in due course add any such thing but we won't do it in a big bad "scenario-solving" rush for classes.

That seems like the right call. If anything, I would like to have support for classes that produce read-only instances and sealed instances (it’s still easy to accidentally add properties to an object) – both of which are tricky if subtyping is involved. I don’t see use-before-definition as too problematic, but there might be factors that I’m not aware of.

There are: where is the super call and what barriers are required to throw on use-before-init across the superclass initialization flow?

We can defer these by deferring guards and const instance properties, and tried to do so. But IIRC at least Waldemar was not happy leaving writable instance properties usable (with default value undefined) before being initialized.

# Brendan Eich (14 years ago)

Brendan Eich wrote:

We can defer these by deferring guards and const instance properties, and tried to do so. But IIRC at least Waldemar was not happy leaving writable instance properties usable (with default value undefined) before being initialized.

Of course, Dart allows this and discloses null on use before initialization:

class Foo { var a; Foo(a) { print(this.a); this.a = a; } } main() { var foo = new Foo(42); print('main: ' + foo.a); }

Tested at dartlang.org.

# Mark S. Miller (14 years ago)

I agree with Waldemar. Classes aside, since code like

{ //...foo... let x = 3; function foo() { return x; } //... }

is statically legal, and is only wrong if foo is called before x is initialized, the dynamic dead zone is very valuable. Otherwise, the call to foo() silently proceeds with a meaningless result.

If you'd really rather have silent meaninglessness, use "var" instead of "let".

# Brendan Eich (14 years ago)

Mark S. Miller wrote:

I agree with Waldemar. Classes aside, since code like

{ //...foo... let x = 3; function foo() { return x; } //... }

is statically legal, and is only wrong if foo is called before x is initialized, the dynamic dead zone is very valuable. Otherwise, the call to foo() silently proceeds with a meaningless result.

If you'd really rather have silent meaninglessness, use "var" instead of "let".

Classes are sugar for objects with properties, though -- rememeber, we agreed to sugar the protoypal pattern, not the closure pattern.

A declared variable binding is different from an object property. They aren't the same thing.

And properties can be used before initialization in JS today (and in Dart -- you Google guys are not all following the same rules :-P).

It seems to me you're not agreeing or disagreeing with anything about classes as prototypal sugar, rather you're trying to reason about properties by pointing to let binding rules. Last July I flagged classes as subject to conflict and confusion in TC39 due to this declaration vs. property conflation. If we can't agree to avoid it by letting properties by properties, then classes are indeed "out" for ES6 -- and out of Harmony for now.

# Bob Nystrom (14 years ago)

On Fri, Mar 16, 2012 at 10:48 AM, Brendan Eich <brendan at mozilla.org> wrote:

Not hermeneutic spirals, just circles. Feels like the last year (we cut off ES6 proposals, modulo exceptions/tweaks, last May; we had a big-ish classes strawman synthesized from several prior proposals; we lost Bob Nystrom to Dart).

I'm still listening and open to helping with classes in JS if I can.

I've been quiet lately because I've felt like the consensus (or lack of consensus, if that makes sense) was that people here and on TC39 were moving in the direction of things like |> and other "object combinator"

like operators in order to define kinds-of-things instead of a more static-baked-into-the-grammar approach like class syntax.

I personally think there's room for both (in much the same way that there's room to have both closures and objects in a language, even though each is the poor-man's other), but the vibe I got from the messages here after the last TC39 meeting was that things weren't gelling with class syntax.

It's a deeply hard problem. Most languages I can think of haven't added new large-scale grammar additions like after they've reached maturity (maybe enums in Java are a counter-example?), and the JS community has very strong and divided opinions about classes. Coming up with a class syntax that's rich enough to be worth buying but small enough to not freak the anti-class establishment is tricky.

I think it would be really cool to have a single language that gave me classes where that made sense and one-off objects and straight object-delegation where that was a good fit, but I'm more open to kitchen-sink languages than most. A big part of JS's appeal is its minimalism so it's hard to sacrifice that for a feature that some users dislike and won't use.

Minimal classes had a good subset of TC39 supporting last summer in

Redmond, but we got hung up future-proofing use-before-initialization for const and guards, if I recall correctly. The notes from the July meeting should cover this.

That's my recollection too. Seems like a strange hangup given that you can't do that now as far as I understand so not being able to do it in classes either wouldn't be a loss, but I'm not on TC39 so I don't have all of the context and insight here.

Either way, I'm still around and up for helping if I can.

# Mark S. Miller (14 years ago)

Sorry, I'd dropped too much context. Out of context, it looked like an argument that could be applied both to instance variables and to lexical variables. As applied only to instance variables, I'll hold off until I have a coherent opinion ;)

# Bob Nystrom (14 years ago)

On Fri, Mar 16, 2012 at 4:22 PM, Brendan Eich <brendan at mozilla.org> wrote:

And properties can be used before initialization in JS today (and in Dart -- you Google guys are not all following the same rules :-P).

This is definitely the strangest possible venue for discussing Dart, but...

That isn't entirely true. For non-final variable, yes, they can be used before initialization. (Or, maybe more accurately, all variables are implicitly initialized to null at the moment of instantiation before the constructor body is invoked.) However, for final fields (i.e. single-assignment instance properties), they must be initialized before the constructor body (in the C++-like constructor initialization list) and the initializer does not have access to this. Final fields cannot be observed before explicit initialization.

Honestly, it's kind of a pain. It was designed that way, I think, for performance reasons, but it just ends up making it harder to use final fields. You end up not be able to use them if you want to do non-trivial initialization or circular references.

Anyway, back to JS... ;)

# Aymeric Vitte (14 years ago)

The first question maybe in all these discussions is what is needed or not (in real life).

In BTF discussions I gave an example where (surprisingly) for an app there were a very few prototype like declarations.

Because I just did not need it for this app.

The second question is maybe whether ES is designed for frameworks or apps, I will go for the second one, apps do not necessarly need frameworks, libraries, etc, and frameworks do help developers not to understand what they are doing

Then adding classes or such looks to complicate more things while existing prototype behavior is good

Maybe the focus should be put more on performances

Le 17/03/2012 00:22, Brendan Eich a écrit :