Re: [WebIDL] prototype chains, multiple inheritance, mixin interfaces

On 23/11/10 18:47, Brendan Eich wrote:
> On Nov 23, 2010, at 4:12 AM, Andrew Oakley wrote:
> 
>> Because it is not possible to get an objects prototype (except for 
>> with the completely non-standard, deprecated property __proto__),
> 
> This is not true: ES5 has Object.getPrototypeOf(obj), equivalent to 
> reading obj.__proto__.

I hadn't spotted that one. We haven't implemented ES5 yet, so I'm not as
familiar with that specification. Presumably this should walk up the
chain to [PrototypeRoot], or what would be concrete classes in the
proposal from the TC39 meeting.

> All abstractions leak on the web, which does use __proto__ if it's 
> there and which is starting to use Object.getPrototypeOf. Even 
> without these reflection APIs, prototype relationships can be 
> discovered by overriding, shadowing, and observing.

Yes, but as long as *something* is specified and implemented across
different browsers we should be OK.

> The ECMAScript global object is not on the prototype chain of some 
> other (Window) really-global object. The two are the same (which 
> means Window must not be a "host object" in ES5 terms; see 8.6.2). 
> ECMA-262 requires builtins such as parseInt and eval to be "own" 
> properties of the global object (|this| in global code, AKA |window| 
> and |self| in browsers).

Yes, it appears that window.hasOwnProperty("parseInt") returns false
with that implementation. Oops.

> How do you implement ES5's Object.getPrototypeOf? There must be some 
> overhead in mapping the MI in your "objects in the system" onto the 
> C3-linearized chains of JS objects reflecting those native objects. 
> Linearization is not free in light of Object.getPrototypeOf.

We store both the linearization and the list of interfaces that this
object directly inherits. The chain to [PrototypeRoot] is the first
object in the list of directly inherited interfaces. It's probably not
really necessary to store the whole list, the first item in the list
would probably be enough.

> This is a trade-off. It can matter for code size and performance. It 
> also matters for non-JS bindings, e.g. Java and C++, as noted in
> this thread.

Java/C# integration would be much easier if we followed the single
class, multiple interface inheritance rules.  I think its a good pattern
to use for C++ as well.  I agree that in most languages it seems much
more sensible to use the model proposed by T39.  I think WebIDL should
use whatever model is most appropriate for each language.

> C3 is reasonable in my opinion, but it's strictly more complicated 
> than single inheritance with mixins implemented by "copying" (or as 
> if they are macros). If JS developers do not need reified mixin 
> interfaces with .prototype properties, then simpler wins. That was 
> our judgment last week at the TC39 meeting.

The reason I implemented multiple inheritance like this is so that you
do have interface prototype objects that can be modified by JS
developers.  It also allows us to dynamically change what extra things
an object inherits from (yes, thats horrible).

> We were hard pressed to find abstract or mixin interfaces that
> needed to be reflected into JS. EventTarget is moving up to be a
> common prototype in the DOM hierarchy. Other examples showed up as
> types of parameters in WebIDL and bindings for languages such as
> Java, but not in JS.

OK, I hadn't looked at whether the DOM hierarchy could be rearranged to
make life easier, I wanted to make sure we used hierarchy specified as
much as possible to avoid any compatibility problems.  Assuming the
major browsers implement the specified hierarchy, someone will rely it.

> Did we miss something?

I don't think so, I just wanted to make sure this approach (or similar)
had been considered.

Thanks

-- 
Andrew Oakley

Received on Wednesday, 24 November 2010 11:14:41 UTC