[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