[e-lang] Sketch of multiple inheritance in E

Kevin Reid kpreid at mac.com
Tue Mar 10 17:05:29 EDT 2009


I just wrote <http://rosettacode.org/wiki/Multiple_inheritance#E>.

Quote: [[[

E does not have multiple inheritance as a built-in feature. In fact, E  
only has inheritance at all as a light syntactic sugar over delegation  
(message forwarding). However, using that facility it is possible to  
implement multiple inheritance.

This is a quick simple implementation of multiple inheritance. It  
simply searches (depth-first and inefficiently) the inheritance tree  
for a method; it does not do anything about diamond inheritance. These  
shortcomings could be fixed if more powerful multiple inheritance were  
needed.

]]]

(Fixing diamond inheritance is a little bit tricky, because it means  
that if you have A isa B isa D and A isa C isa D, then B's behavior  
(whether its super-call goes to D or C) has to depend on the existence  
of C, which is not part of B's definition. However, I believe this is  
*possible*, in a safe way, because B has the "self" reference, which  
is the authority on how the composite object should behave.)

[[[

def minherit(self, supers) {
     def forwarder match [verb, args] {
         escape __return {
             if (verb == "__respondsTo") {
                 def [verb, arity] := args
                 for super ? (super.__respondsTo(verb, arity)) in  
supers {
                     return true
                 }
                 return false
             } else if (verb == "__getAllegedType") {
                 # XXX not a complete implementation
                 return supers[0].__getAllegedType()
             } else {
                 def arity := args.size()
                 for super ? (super.__respondsTo(verb, arity)) in  
supers {
                     return E.call(super, verb, args)
                 }
                 throw(`No parent of $self responds to $verb/$arity`)
             }
         }
     }
     return forwarder
}

The task example:

def makeCamera(self) {
     return def camera extends minherit(self, []) {
         to takesPictures() { return true }
     }
}

def makeMobilePhone(self) {
     return def mobilePhone extends minherit(self, []) {
         to makesCalls() { return true }
         to internalMemory() { return 64*1024 }
     }
}

def makeCameraPhone(self) {
     return def cameraPhone extends minherit(self, [
         makeCamera(self),
         makeMobilePhone(self),
     ]) {
         to internalMemory() {
             return super.internalMemory() + 32 * 1024**2
         }
     }
}

And testing that it works as intended:

? def p := makeCameraPhone(p)
 > [p.takesPictures(), p.makesCalls(), p.internalMemory()]
# value: [true, true, 33619968]

]]]

-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>




-- 
Kevin Reid                            <http://homepage.mac.com/kpreid/>




More information about the e-lang mailing list