- From: Andrew Oakley <andrew@ado.is-a-geek.net>
- Date: Tue, 23 Nov 2010 12:12:30 +0000
- To: Cameron McCormack <cam@mcc.id.au>
- CC: "public-script-coord@w3.org" <public-script-coord@w3.org>
On 19/11/10 21:39, Cameron McCormack wrote: > 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: [removed TC39 proposal] For our browser (ANT Galio Browser) we have implemented something that we believe is close to implementing the current spec (described in terms of mixin prototype objects) using multiple inheritance. We use the same linearization as Python and Perl6, relevant links can be found on wikipedia here: http://en.wikipedia.org/wiki/C3_linearization Because it is not possible to get an objects prototype (except for with the completely non-standard, deprecated property __proto__), and the WebIDL specification does not specify any odering we can inherit from whatever we like without issue, as long as we have a sensible resolution order (C3) and [[HasInstance]] implementation. Our [[HasInstance]] implementation walks up the prototype chain directly rather than using the linearization and only looks at the first interface in the list if if we have multiple inheritance. The list that [[HasInstance]] walks is the prototype chain to [PrototypeRoot] (we make sure we specify those objects first in the input to the linearization algorithm). These are the same as the "concrete" interfaces from the TC39 meeting proposal. The advantages of this approach were: * It was fairly easy to implement (but I'm not sure how much effort it would be for others); * We can have interface prototype objects for all of the interfaces and updates to these will affect all objects that inherit from them; * The constants work as expected; * We don't need to allocate much memory - we create the interface and interface prototype objects on demand so if you don't access them directly they don't get allocated; * We can use the same mechanism to make the global inherit from both Window.prototype and the ECMAScript global object. In terms of specification, it wouldn't seem unreasonable to simply have the inherited interfaces in the appropriate order in the specification and have the CS linearization code deal with it, so [PrototypeRoot] can go away. I think [Supplemental] and [NoInterfaceObject] have other uses elsewhere so we have to keep those (but remove this use case). The only real downside I can see of doing this is that we don't use the [[Get]], [[CanPut]], and [[HasInstance]] described in the ECMAScript specification because of our more complicated inheritance. These methods walk up the prototype chain by calling the same method on the [[Prototype]] object, but we could have a linearization stored in there which we will have to walk along. On a positive note we actually use the same implementation for all objects in the system - the behaviour is not changed for objects with single inheritance. We haven't seen any compatibility issues with this change, but our browser doesn't get the same level of use that others do. I don't think this way of dealing with multiple inheritance has caused much confusion for Python and Perl users, it tends to "just work" without really having to think too much about it. Is this a reasonable way of dealing with the problem? Are there any issues with doing this? Is it any better than the proposal from the TC39 meeting? -- Andrew Oakley
Received on Tuesday, 23 November 2010 12:09:54 UTC