default constructors and implicit super() insertion

Brendan Eich brendan at
Wed Jun 27 13:54:37 PDT 2007

> While I see that it can be useful, I remain concerned that this will
> seem confusing to novices. Why do I need that colon? What does "x=x"
> mean? Why did I get the wrong result when I did the following, which
> looks a lot like the above?
>   // novice error 1
>   class C {
>     function C(x, y) {
>       x=x;
>       y=y;
>     }
>     var x, y;
>   }

One could argue that novices will be baffled by a great many things,  
not only in ES4 (classes, non-nullable type annotations) but in ES3  
(higher order functions, with statements, eval dynamic scope, etc.  
etc). Novices learn, sometimes after bruising a toe or finger.

To argue briefly against your point in particular: settings are odd- 
looking, distinguished syntax for several reasons, including so that  
the scope for LHS and RHS can differ usefully.

To take your position, this is the only such case, and it could be  
misleading, or at best a useful but odd little feature hanging on  
otherwise fairly simple rules for mentally evaluating = operators  
near or within class constructors.

> What happens when an initialization requires a bit of logic? Suppose I
> have a "title" property of a MyDocument object that is non- 
> nullable. If
> the name is passed in, it is used. Otherwise, one is generated (e.g.,
> "Untitled1").

The ?: operator stands ready! Seriously, there's no problem using  
arbitrary expressions, including calls to static or outer-scope  
helper functions.

> I'm not really an expert, but in terms of overall simplicity, my
> preference is
>    a) provide a clear way to disambiguate between members
>       and other variables in scope in *all* cases. (this may
>       already exist)

As for non-class functions (where |this| is *not* on the scope chain  
implicitly), |this.x| works.

>    b) allow non-nullable types to be initialized in the
>       constructor in the body of the constructor, as
>       opposed to creating new syntax

Then the UninitializedError hazard arises, the dual of the NPE. True,  
it is limited in extent (duration, ... not sure what the right word  
is here) to the activation of the ctor. But given non-nullable type  
annotation syntax, why not have syntax (remember, "UI") specialized  
to avoid the UE hazard altogether?

>    c) make it a *runtime* error to read an unitialized
>       non-nullable object. also make it a runtime error
>       to leave a constructor without having initialized
>       each non-nullable field.

This point (c) is really two points: make it a runtime error to read  
an uninitialized non-nullable slot; and a restatement or elaboration  
or implication of point (b). Taking just the first point as (c), you  
are saying what must be the case no matter what, unless we do require  
DA and make it an error not to initialize instance vars in  
constructors. No argument there.

>    d) optionally, make it a compile-time error to exit a
>       constructor without having initialized each
>       non-nullable object.
>    // my preferred syntax:
>    class Position {
>       var x: Number;
>       var y: Number;
>       var target: Object!;
>       function Position(x: Number, y: Number, target: Object!)
>       {
>          this.x = x;
>          this.y = y;
> = target;
>       }
>    }

"optionally" here could mean strict mode. It should not mean standard  
mode. It should not mean "implementation defined". We want a  
normative spec for both optional-at-implementation's-discretion  
strict mode, and for standard mode, in order to uphold interoperation.

> If this discussion is already closed or if I am barking up the wrong
> tree, please feel free to just say so. Thanks.

Not at all, this list exists exactly for this kind of discussion. So  
thanks back!


More information about the Es4-discuss mailing list