On Oct 13, 2011, at 1:05 PM, Russell Leggett wrote:

> [snip] 
> >> I want to compose objects:
> >>  var result = cookUpTheBehavior(goodies, stuff) <| 
> >> initializeTheState(args);
> >
> > You want something else, then. Just because you want B does not mean A is 
> > useless or less useful or not JavaScripty.
> >
> >> With a decent Object.extend() we'd have a clean way to build objects 
> >> without having to look up Crockford's web pages every time we try a 
> >> different variation.
> >
> > Object.extend is on the agenda. It's not the same as <|. Two different 
> > tools for two or more different jobs.
> 
> I want these two tools to work together!   I want a standard property cloner 
> and a composition operation that creates objects from a behavior object and 
> data object.  Wouldn't that be nice?
> 
> I agree with this - at least in the sense that I think it might be an 
> appropriate time to take a higher level perspective of all the aspects of 
> JavaScript object definition and reuse. That seems to be a lot of what is 
> being discussed now from class literals to the <| operator to new <Object> to 
> traits. I understand the value of decomposing these ideas down into 
> orthogonal part which can be used independently and combined to create a 
> variety of useful abstractions. However, I think that creating something 
> cohesive is really important, and in the end we will want to provide a clear 
> path for the common cases.
> 
> I find it a problem that there is a standard pattern in JavaScript for 
> creating "classes" but there isn't a real name for it. We have constructor 
> functions and prototypes. Even the Rhino book is forced to say, "For lack of 
> a better term, I will use the word "class" informally in this chapter." Then 
> if you want to extend one of these things, you'll have to basically resort to 
> a library or some recipe of your own. It's black magic. And worse, all the 
> built-ins use the pattern, so we're basically going to have it around forever.
> 
> I understand that this is sort of what <| is for, and it is potentially what 
> class literals are for, I guess my point is just that I think it should be a 
> high priority for es.next to result in some definitive way of saying:
> create a thing Foo, including its constructor and at the very least methods 
> (including get/set methods)
> create a Bar that extends Foo, including its constructor...
> This is what Coffeescript provides with class and extend. I get the feeling 
> that using class would be too loaded. If class is going to be used it sounds 
> like people would like more than to have sugar for the existing pattern, they 
> would like more and they don't want to harm future proposals. I think this is 
> fair so I would say take the word "class" off the table. This is the reason I 
> had previously proposed <| as more of a generic extension operator. It's 
> already doing a lot of magic when it comes to functions and arrays.
> 
> I'm not sure exactly what the answer is, I'll try to think of something 
> better to propose, I just feel like hashing out the individual pieces like <| 
> and .{ and Object.extend etc. are all discussions that are worse off for not 
> discussing how they should all work together.
> 
> - Russ

Let me take a crack at tying to tie together all the pieces we have been 
talking about.

To start, I want to introduce a new term that I will use to describe an program 
construct that defines the common characteristics that are shared by a probably 
open ended set of similar objects.  I want to avoid common terms like "class" 
and "prototype" for such entities because they carry preconception baggage that 
I want to avoid for now. Instead, I'm going to use the term "exemplar".  While 
there has been some limited usage of the term "exemplar"  in computer science, 
it doesn't have any broadly accepted meaning or carry significant connotations. 
You have to get to the fourth page of a google search for "exemplar" before you 
find anything that is even vaguely related to CS.

In JS today, we essentially have two forms of exemplars.  One looks like this:
     
  function Foo(a,b) {
      this.x = a;
      this.y = b;
  }
 Foo.prototype.method = function () {...};

and makes it easy to parameterize the per instance state of new objects but it 
is awkward to specify the shared behavior of instance objects described by the 
exemplar.  The other form of exemplar looks like this:
  
 var Bar = {
   x: 0,
   y: 0,
   method() {...}
 }

and makes it easy to specify the shared behavior of instances but it is awkward 
to parameterize the per instance state of new objects described by the exemplar.

Are these two forms of exemplars really that different?  There may be reasons 
to prefer one form of expression over the other in various situations, but can 
we find a way to generally use and think about them interchangeably? 

One current difference is in how you create new instances of the exemplars.  
With the function form you say:
   var newObj = new Foo(1,2);

You can't currently do that with the literal form.  In fact, Bar in the above 
example arguably isn't really the name of the exemplar but rather the name of 
an instance of the exemplar.  The new <Object> proposal addresses this 
difference by permitting us to say:

   var newObj2 = new Bar();

It also address the per instance parameterization issue by giving meaning to:

 var Bar = {
   x: 0,
   y: 0,
   method() {...},
   constructor (a,b) {
      this.x = a;
      this.y = b;
   }
 }

so we can say:
  
   var newObj2 = new Bar(1,2);

This means that from an instance creation point of view the two forms of 
exemplars are pretty much on equal footing.

.{ can be used to make it less awkward to specify shared instance behavior for 
the function form of exemplar (although perhaps not less awkward enough for 
some of us).

<| and super can be used with both exemplar forms to specify inheritance:

  var SubFoo = Foo <| function (a,b,c) {
      super.constructor(a,b);
      this.z = c;
  };

  var SubBar = Bar <| {
      z: 0,
      constructor (a,b,c) {
         super.constructor(a,b);
         this.z = c;
      }
  }

Another  issue in unify the two exemplar forms is what happens if they are mix. 
Such as:

  var SubFooLit = Foo <|  {
      z: 0,
      constructor (a,b,c) {
         super.constructor(a,b);
         this.z = c;
      }
  }

and 

  var SubBarFunc = Bar <| function (a,b,c) {
      super.constructor(a,b);
      this.z = c;
  };

I think I can formulate reasonable rules for <| that make both of these also 
work.

The final remaining issue is instanceof and I also think we can also make this 
work with cross inheritance between the two styles of exemplars: we need to 
automatically generate a "prototype" property for "constructor" methods defined 
in object literals that back references the resulting object.

If we did these things we would pretty much have a common story of objects, 
defined using exemplars, instantiated using new, and supporting inheritance 
expressed in terms of exemplars.  There are two equally valid alternative 
styles of exemplars, but they are fully interoperable with each other so it is 
really a matter of style or circumstance as to which you might choose to use. 
Other compositional forms can be defined in terms of higher-order functions and 
should be applicable to either exemplar formulation.

We might even choose to define an additional interoperable exemplar form that 
combines the best characteristics of the two existing forms.

This is a more complicated tory then simply having a traditional class model 
such as Dart is using.  However, we have an existing language with existing 
featuures with a wide range of usages patterns so whatever we do with "classes" 
we still have to accommodate what currently exists in JS. We are never going to 
have as simple a story as a do-over language such as Dart. But I do think we 
can craft a understandable story where all the pieces fit together relatively 
nicely.

Allen













    
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to