An experiment using an object literal based class definition pattern

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Aug 5 09:32:50 PDT 2011


On Aug 5, 2011, at 7:46 AM, Brendan Eich wrote:

> On Aug 4, 2011, at 11:00 PM, Allen Wirfs-Brock wrote:
> 
>> On Aug 4, 2011, at 8:39 PM, Axel Rauschmayer wrote:
>> 
>>>> Another idea was an alternative way to express the "extend" operator for literal property definitions.  Doug Crockford suggested the following syntax:
>>>> 
>>>>     obj.{
>>>>        prop:1,
>>>>        prop:2
>>>>        }
>>> 
>>> It looks nice, but the operator should also work for a RHS that is not an object literal.
>> 
>> But using . as the operator it would be ambiguous with normal property access.  A different and unique operator wouldn't have the problem but also wouldn't look so nice and the primary motivation for the operator is for use in expression such this post is about.
> 
> Still, unliked <|, an extend function (built-in module export) would be useful in more cases, based on Prototype and other libraries' Object.extend.

Agreed, we would still want a functional form such as Object.extend.
> 
> 
>>  An alternative that could work would be to allow a parenthesized expression to follow the dot.
> 
> ECMA-357 (E4X) uses that for something we want to get rid of (filtering predicates, 'with' like things). So a.(b) as Object.extend(a, b) is possible, but again there is not strong need for an operator.
> 
> Using a.{p1:v1,...} syntax is attractive in its own right, but not as a final syntax in lieu of classes.
> 
> 
>>> How about rewriting this as follows?
>> I did something similar in my first go at this, but there is a problem...
> 
> Right, the desugaring from class syntax is fragile and error-prone.

I not so sure I agree.  It isn't obvious that this code pattern is particularly any more fragile, error prone, or less toolable than some of the class syntax alternatives that have been discussed.  Particular, if a programmer sets up an editor template that inserts:
const classname = subclass <| function ( ) {
   super.constructor();
   this.{

   };
}.prototype.{

}.constructor.{

};


It isn't clear why this is necessarily any more fragile (or less temptable) than for example:

class classname extends superclass {
  constructor() {
    this.  =  ;
  }

prototype:

class:

}

or other forms of class declarations we have discussed.

> It's clever, but it doesn't eliminate the higher-level win of consolidated class syntax -- provided we can agree on class-method sections, class-side inheritance, and the other open issues.

That agreement is the rub. As you captured in the day 2 meeting notes we are a long ways from agreement on those issues.  And, some of the progress we have been making has the feel of committee compromises in order to make progress rather than strong cohesive design.  Also, as dherman keeps reminding us, time is short if we want to make our 2013 target.

The simple extensions I'm proposing supports a straight forward coding pattern that address all of the above issues  without irrecoverably baking into the language a complex syntactic form that locks in those decisions.

JS programmers were able to create innovative and useful support for both classical and  prototypal inheritance abstraction using ES1-3 even though the language support for doing so was weak and incomplete. ES5 provided improved support for creating such abstraction patterns but is still missing some key primitive capabilities.  We are very close to agreement on filling in all the known remaining primitive holes for ES.next.  In particular, the key extensions I used in the collections experiment are:
   *  modules and modules exports
   *  the <| operator -- defines the [[Prototype]] of a literal
   *  the .{ operator -- extends the LHS object with properties from an object literal
   *  concise method properties in obj lits - foo() {} defines a non-enumerable function data property
   *  super propertry references
   *  private names created via Name.create
   *  using [expr] in the propertyname position in an object literal, evaluate the expr to get the name

The collections experiment seems to be a pretty good demonstration that with these extensions we will have reached at least the power of Smalltalk for creating class-based abstractions. Given the availability of those extensions, who knows what sorts of innovative abstraction ideas will emerge from the same JS programmers who accomplished so much using just  ES3.  Rather than baking into ES.next a syntactic class abstraction that is largely inspired from static OO languages experience lets just make these primitives available and see what happens in the real world.  If a single dominate abstraction pattern emerges then we can consider baking it into ES.next.next syntax.

Allen






-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110805/ba1a5512/attachment-0001.html>


More information about the es-discuss mailing list