Finding a "safety syntax" for classes

David Herman dherman at
Sat Mar 24 23:45:21 PDT 2012

On Mar 24, 2012, at 5:54 PM, Allen Wirfs-Brock wrote:

> I primarily favor sticking with "constructor" because the safety/maximally-miminal proposal is all about being conservative...

I think you'll find what I'm saying is as conservative as what you've been advocating. Your reply demonstrates that we've been talking past each other.

>>    a) spell it "new" -- ergonomics trumps corner cases; hard cases make bad law
> deviates from chapters 13 and 15.  
>  (class () {})  isn't interchangeable with (function () {}). Shouldn't it be?

When I say "spell it 'new'" I mean "the *surface syntax* is spelled 'new'". That has nothing to do with the semantics. The semantics is described in point b). Keep reading...

>>    b) desugar it to the constructor function and the p.constructor property only
> but presumably means that an instance method named new can't be defined using a class definition.

Not with the declarative syntax, no. But easily enough imperatively:

    class C { new(x) { this.x = x } } // defines C.prototype.constructor === C = function() { console.log("I am C's 'new' method") }

Notice the comment: the class definition uses 'new' for the surface syntax, but that defines C.prototype.constructor, *not* If you want to add a prototype method called 'new', you can do that imperatively, the same old way as ever in JS.

> Or, perhaps only if "new" is explicitly string quoted as a property name. "new" is not a totally unreasonable method name.  Also presumably means that defining an instance method named constructor is disallowed.

That's true, "new" is not an unreasonable method name. It's still a rare method name. Syntax is about optimizing for common cases. With my proposed syntax, you don't have a declarative way to create a prototype method called "new" but you still have an imperative way to do it, the same old way as before.

>>    c) i.e., don't create a property -- no more prototype pollution please
> I presume you mean it also doesn't define a p.constructor property.  This has similar problems to a).

No, no, see b) -- it *does* define a p.constructor property!

What I've been trying to explain is that we can use "new" for the *surface syntax* but desugar it just the same as the "constructor" version: the constructor becomes both the value of the class and the p.constructor property.

> It deviates from the legacy ES "class model"

It implements *exactly* the legacy ES class model.

> Also, most instance inherit from Object.prototype so they will still have an inherited "constructor" property whose value is Object.

They will not, because p.constructor is the constructor.

> A very common idiom is to query the "class" of an object.  Just look how frequently you see could like p.class in Java or Ruby code  or( p class) in Smalltalk code. Thew equivalent of this using ES chapter 13/`5 objects is p.constructor.  Which would you prefer to see in future ES code p.constructor===q.constructor or

My proposal is not, and has never been, to change the C.prototype.constructor idiom. It is to choose a different surface syntax that desugars to *exactly* the classic idiom.


More information about the es-discuss mailing list