On May 30, 2012, at 2:17 AM, T.J. Crowder wrote:
> On 30 May 2012 05:09, Brendan Eich <[email protected]> wrote:
> ...
> So A remains
>
> obj.{x: val, y: val};
>
> ...where these are [[DefineOwnProperty]]
>
> and B becomes
>
> obj.(x = val; y = val);
>
> ...where these are [[Put]]
>
> Is the idea to _only_ have B, or to have both A and B? I see clear use cases
> for B. I'm not immediately seeing them for A but I came late-ish to the
> discussion.
Mustache (A) is partially about more concise expression of object abstraction
patterns, particularly WRT method properties.
Consider the following exemplar that is typical of code you might see today for
defining a class like abstraction:
//Define a simple Point abstraction over objects
function Point (x,y) {
this.x = x;
this.y = y;
}
Point.prototype = function plus(aPoint) {
return new Point(this.x+aPoint.x,this.y+aPoint.y
};
Point.prototype = function distanceOrigin() {
return Math.sqrt(this.x*this.x+this.y*this.y)
};
Using mustache you could say:
//Define a simple Point abstraction over objects
function Point (x,y) {
this.{x, y};
}
Point.prototype.{
plus(aPoint) { return new Point(this.x+aPoint.x,this.y+aPoint.y)},
distanceOrigin() {return Math.sqrt(this.x*this.x+this.y*this.y)}
};
This is the just the basic Es1-3 "class" pattern made more concise and arguably
more readable (once you learn the syntax). To me, it is a more direct
expression of the programmer's intent.
But there is more to concise methods with Mustache than just conciseness of
expression. There is an important semantic distinction.
The methods defined in in the mustache example are non-enumerable properties,
just like the methods defined in a class declaration and the methods of the
built-in objects. This is almost surely what you want for methods that you are
defining on a prototype, yet with ES5 you have you use Object.defineProperty to
accomplish it and prior to ES5 it wasn't possible at all.
Most importantly, mustache provide a syntactic context for binding |super|
references in methods:
Image I need to over-ride a prototype method on a per instance basis. For
example:
let p100 = new Point(50,50);
p100.{
distance(aPoint) {return Math.max(super(aPoint), 100)} //max distance is
100
};
This correctly binds the per instance "distance" method so the |super|
reference works correctly. The alternative using = :
p100.distance = function (aPoint) {return Math.max(super.distance(aPoint),
100)}
would not work correctly and would produce either a static or dynamic error on
the super reference.
In the super proposal
http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super#imperatively_binding_super
, installing such a method onto an object while maintaining a correct |super|
binding required use of Object.defineMethod. It's been argued, and I agree,
that defineMethod in this context would be too error prone. Mustache eliminates
the need for defineMethod for these most common cases.
You might argue that |super| only makes sense within a class. However, the
above example could easily be rewritten using class syntax:
class Point {
plus(aPoint) { return new Point(this.x+aPoint.x,this.y+aPoint.y}
distanceOrigin() {return Math.sqrt(this.x*this.x+this.y*this.y)}
constructor(x,y) {this.{x,y}}
};
let p100 = new Point(50,50);
p100.{
distance(aPoint) {return Math.max(super(aPoint), 100)} //max distance is
100
};
Using a class to define the abstraction doesn't change the fact that there are
scenarios where it is useful to dynamically add per instance methods that
augment (via super calls) prototype behavior.
Basically, mustache should be seen as the normal way to define methods on
pre-existing objects. Its more concise, correctly makes methods
non-enumerable, and support super references.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss