Alex, Erik, and I had a twitter conversation that eventually ran into the 
inevitable  limit of  effective communications using 140 character messages.  
This seems like a better place to capture and discuss the issues...

The conversation started about the new DOM API that Dart is proposing and my 
question of why a new language is need to prototype such an interface.  Why not 
just develop it in JavaScript.

Erik mentioned that Proxies are needed and I replied that experimental 
implementations are available.

Alex also mentioned that a "use strict" for the DOM is needed, but we didn't 
follow up on that.  I'd like to know more about what that meant.

Finally Alex said that he needs "extensible Array types" and said that "the 
committee hasn't moved quickly on that" . A subsequent message clarified that 
we was talking about "subclassing Array".

I said that <| supports "array subclassing" (in fact, this was the original use 
case that gave rise to <|) and Alex asked to be reminded how that would work 
and what about the length property.

I responded:

function createArraySubclass(proto, ...values) {
   return proto <| [...values];
}

If I'd had more characters I would have said that this creates a new object 
whose [[Prototype]] is proto and that the object has all the special 
characteristics of an array object.  In particular Object.isArray will report 
true for it and the object has the special behavior of automatically updating 
the length property when elements are added past the end.  It really is an 
array object, just one with a different [[Prototype]].  If you want it to also 
inherit from Array prototype you can define proto such as:

var proto = Array.prototype <| {/* additional "subclass" methods */};

Alex respond that new and instance of didn't work.
(using new to create DOM nodes is one of the characteristics of the Dart DOM 
design).

It took me three tries to get all the typos out, but I showed how new could be 
made to work:

var SubArray = Array <| function(...values) {
   return Object.getPrototypeOf(this) <| [...values];
}
   
/* add subclass methods */
SubArray.prototype.method1 = function() {...};
SubArray.prototype.method2 = function() {...};
/*or stache it:  SubArray.prototoype.{method1() {..}, method2() {}}; */

then you can say:

var s = new SubArray(1,2,3);
console.log(s.length);  //3
s[3] = 4;
console.log(s.length);  //4
console.log(Object.isArray(s)); //true
console.log(s instanceof SubArray); // true
console.log(s instanceof Array); //true

Alex responded that the proposed class syntax
  class NodeList extends Array { ... }
would also do the trick.

I respond "does class extend as proposed, propagate over-ridden [[internal 
methods]]?  Don't think so?"

Alex that I was being "class syntax hostile...Why the hate?"  I plead 140-char 
terseness. 

However, as I then pointed out, this is one of my issues with the class 
proposals.  They have never been completed to the level of specifying how 
things like subclassing array should be handled.  Alex apparently thought that
    class NodeList extends Array { }
would automatically mean that  NodeList instances would have full array 
instance semantics.  I don't see how that would work.  Would 
    class ExtendedNodeList extends NodeList { ...}  
also result in a class whose instances had array instance semantics?  How about 
in
   function makeClass(sup) {
       class newClass extends sup {...};
       return newClass
  };
  var c1 = makeClass(Array);
  var c2 = makeClass(c1);
  var c3 = makeClass(RegExp);

I just don't see how the class declaration would know when it did or didn't 
have to create special instance objects.

On a related matter, would you define a class whose instances are Proxy 
instances.  The most recent discussions I followed seem to preclude using the 
trick I used above for arrays, something like:

class P extends Object{
   constructor () {
      return Proxy.create(myHandler,Object.getPrototypeOf(this));
  }
}

because they disallow explicit returns from within constructors.  Even if this 
was allowed what would happen for 
class Q extends P {...}

Is there anyway to subclass a proxy-based class and automatically get the proxy 
based behavior in the subclass instances? 

We pretty much concluded with Alex asserting that the class declarations would 
provide a place to hang whatever (language design) hacks are needed to resolved 
such issues.  And I asserted that I was more interested in making sure we had 
the primitive in the language that could be sugared (by library designers into 
these sorts of abstractions).  Nothing new in that basic disagreement about 
approach.

Something we didn't get into, was the issue of how much of existing NodeList 
behavior you would really want to preserve in a new DOM design. I think that 
would be another interesting discussion. 

Alex and Erik may have a different perspective on this little debate and may 
want to emphasize something that I glossed over. So, please do. Regardless, I 
think we stirred up some potentially interesting issues.

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

Reply via email to