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

Brendan Eich brendan at mozilla.com
Thu May 19 18:45:17 PDT 2011


On May 19, 2011, at 3:00 PM, Luke Hoban wrote:

>>> 2) The conventional JS pattern is to place methods on the prototype, not the instance, and many felt that the main thing classes need to provide is a syntax to make this traditional semantics easier to express.
> 
>> This is the big one.
> 
> Class syntax with class parameters instead of explicit constructors can still be defined to produce methods on the prototype, right?
> 
> Andreas' example:
> 
>  class Point(x, y) {
>   public function abs() { return Math.sqrt(x*x, y*y) }
>  }
> 
> Can effectively desguar to:
> 
>  function Point(x,y) {
>    this.x = x; 
>    this.y = y;
>  }
>  Point.prototype.abs = function() { return Math.sqrt(this.x*this.x, this.y*this.y); }

Try a non-trivial constructor that wants instance properties x and y computed from parameters x0 and y0, and does *not* want properties named x and y.

We should not implicitly create instance properties from class parameter names. I did not take Andreas's message as proposing that.

But let's say the instance variables are declared via

class Point(x0, y0) {
  public x, y;
  ... // somehow set x and y in a constructor body
  public function abs() { return Math.sqrt(x*x, y*y) }
}

Why should there be a non-local rewriting of x and y in function abs to this.x and this.y? Just because they were declared via public?

This is too implicit by far. We need the ability to write constructor bodies that initialize instance properties not necessarily named by constructor parameters. Yes, shorthands for the cliché, e.g.

class Point {
  constructor(this.x, this.y) {}
  ...
}

with parameter default values allowed, are good and (I argue) necessary for competitive reasons. But the full constructor form, whatever it is, must enable parameters to be used freely to compute initial values of instance properties, and some instance properties can have parameter-independent initial values.

And in no case should rewriting or non-lexical scope implicitly come into play to rewrite names in methods to reference instance properties. Shorthands, again, are conceivable and possibly important for usability.

In your example, lexical scoping, the fundamental shared value that enabled Harmony, would have readers think x and y in abs refer to the parameters, *not* to the instance properties. The implicit default constructor copies the parameters to the instance properties, true -- but that's not evident from the syntax.

And since we need the ability to write non-default constructors with explicit property setting on the instance, I do not see how the rewriting of unqualified identifier expressions in method bodies can work -- not without mandating public x, y. But we do not want to mandate declaration of instance properties that the constructor (or any other code) might set.


> Or, with private names, to a variant with the captured x and y stored as private fields on the instance.  It's really just a syntax choice between explicit constructor functions and parameterized class definitions.  There are many benefits to the latter, and many modern OO languages seem to be using this style effectively.  

I don't think so. The example needs elaboration to allow for non-default constructor. The non-lexical scope objection applies. And JS is not C# ot any static language. There's a lot to like in many languages but OO does not entail implicit constructors and rewriting.

(I hope you don't mean that the instance (this) should be in the scope chain of each method, because that is non-prototypal and requires a method-clone per instance per prototype (class-declared without keyword prefix) method.)

/be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110519/d879e7be/attachment.html>


More information about the es-discuss mailing list