new instantiation design alternatives

Andreas Rossberg rossberg at google.com
Fri Sep 12 08:26:42 PDT 2014


On 12 September 2014 17:18, Mark S. Miller <erights at google.com> wrote:
> Even when written explicitly, either by an IDE or a human, the
>
> constructor(a, b, c) {
>     this = new super(...arguments);
>     ...
> }
>
> pattern is usually bad. It is fine in a certain special case I mention
> below. It would be a disaster to have this pattern be the default smoothed
> over by a syntactic shortcut. Here's the problem:
>
> ----- at time v1 -----
> class Point {
>     constructor(x, y)
>         this.x = x;
>         this.y = y;
>     }
>     equals(otherPt) {
>         return this.x === otherPt.x && this.y === otherPt.y;
>     }
> }
>
> class ColoredPoint extends Point {
>     constructor(x, y, color) {
>         this = new super(x, y);
>         this.color = color;
>     }
>     // whether we override equals here is not the issue
> }
>
> ---- at later time/revision v2 ----
> class Point {
>     constructor(x, y, fudgeFactor = 0.000001) {
>         this.x = x;
>         this.y = y;
>         this.fudgeFactor = fudgeFactor;
>     }
>     equals(otherPt) {
>         return abs(this.x - otherPt.x) <= fudgeFactor &&
>                 abs(this.y - otherPt.y) <= fudgeFactor;
>     }
> }
> --------
>
> Under normal circumstances, as shown above, this is a valid evolution of the
> Point class, even without examining or revising existing clients like
> ColoredPoint. Since the Point constructor had only two non-optional
> parameters, it could normally assume that existing clients had only called
> it with two arguments. Thus, it would normally be assumed compatible with
> existing clients to add new optional arguments. Passing all arguments by
> default breaks this assumption, making the "fragile base class" problem much
> worse.

Thanks Mark, this was exactly my concern as well. In general, it is
bogus to assume that the parameter lists of a base and a derived
constructor bear any relation. And even if they happen to do so today,
they might no longer tomorrow, which your example demonstrates quite
well. So just silently forwarding an argument list nilly-willy is
broken.

I think it's fine to have a default "new super" call, but only with an
empty argument list. That would also be more in line with what other
languages do.

/Andreas


More information about the es-discuss mailing list