- From: Cameron McCormack <cam@mcc.id.au>
- Date: Sat, 20 Nov 2010 10:39:26 +1300
- To: public-script-coord@w3.org
The proposal to solve the prototype chain with multiple inheritance problem that was hashed out at the recent TC39 meeting, and which had broad agreement, is as follows: * Have two kinds of interface. One is more concrete (almost class- like), since it results in objects/properties/methods existing in the JS environment. The other is more abstract, and is used for mixing in behaviour to the class-like ones. * The concrete interfaces have only single inheritance. For concrete interfaces, only a single name will be allowed on the RHS of the colon. * The abstract interfaces allow multiple inheritance, and get mixed into the concrete interfaces using the ‘implements’ statement. * The abstract interfaces are structural types, and thus don’t have a name. All of the properties they would define go on the prototype object for the interface on the LHS of the implements statement. Only concrete interfaces get interface objects and prototype objects. Thus there is no way to determine if an object implements a given abstract interface. * The mixin prototype object goes away. * All abstract interfaces are thus implicitly [Supplemental] and [NoInterfaceObject]. There’s no need to define [Supplemental] then, and [NoInterfaceObject] might be able to be dropped. * No special [[HasInstance]] behaviour is now needed, since the only interfaces you can test with ‘instanceof’ are the concrete interfaces, which form a single inheritance hierarchy. We can just use the standard [[HasInstance]] behaviour of Functions. * [PrototypeRoot] can go away, since there is no multiple inheritance of concrete interfaces. WebKit, Gecko, Chromium and IE people seemed happy with this. One issue I thought of since then is what to do if mixin interfaces want to define constants, and they want them to appear on an interface object with the abstract interface’s name? This comes up in SVG, for example: interface SVGZoomAndPan { const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0; const unsigned short SVG_ZOOMANDPAN_DISABLE = 1; const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2; attribute unsigned short zoomAndPan setraises(DOMException); }; interface SVGSVGElement : SVGElement, SVGZoomAndPan, … /* various other interfaces */ { … }; So in the new system, SVGSVGElement (which ultimately inherits from Node) is a concrete interface, and SVGZoomAndPan is an abstract one. SVG 1.1 currently requires that `SVGZoomAndPan.SVG_ZOOMANDPAN_MAGNIFY` be a property. So if SVG were rewritten to use Web IDL, and SVGZoomAndPan were an abstract interface, then its constants would only appear on SVGSVGElement (and SVGSVGElement.prototype). We could say that a property SVGZoomAndPan exists on the global object, and it just has the constants on it and no prototype property, but it then does look like an interface object that you might want to use on the RHS of an instanceof. Does it matter particularly that these structural types could cause these objects-exposing-constants to exist? An alternative would be to just require that the SVGZoomAndPan object exists with these constants as a legacy-required thing, and that for future (other) specs, script authors would just need to look up the constants on the concrete interface being mixed in to. -- Cameron McCormack ≝ http://mcc.id.au/
Received on Friday, 19 November 2010 21:40:05 UTC