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

Reply via email to