Demystifying "most Smalltalk's don't directly support multiple
inheritance"
Alexandre Bergel
Alexandre.Bergel at cs.tcd.ie
Mon Jun 26 09:45:56 UTC 2006
> You're right and as many times before I appreciate your expertise!
> There is indeed a gap between the time of setting the super class
> reference (bytecode i-1) and when the VM starts using it (bytecode i
> +0). But from there on, method lookup and method activation is atomic.
Yes, method lookup and method activation are atomic. But I had in
mind if a super call does a Processor yield. The method containing
the super invocation contains the ref of the second super class. But
humm... perhaps it does not matter after all. If a method has to be
lookup in other classes, then if will always have to be. I have to
think a bit more...
But my general feeling is that multiple inheritance is complicated.
Much more than traits. I was visiting the team of Bertrand Meyer in
Zürich last week. I really wanted to understand the difference
between stateless traits, stateful traits and multiple inheritance à
la Eiffel. It seems that everything that can be done with state(less|
ful) traits can be done in Eiffel. The only difference is about
complexity to achieve a particular behavior. With traits the
flattening property makes the whole story simple, while in Eiffel the
static type system makes it horribly complicated.
For instance, here an example in Eiffel:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class C1
feature
foo is
do
print ('1')
end
end
class C2
inherit
C1
rename
foo as bar
redefine
bar
end
bar is
do
print ('2')
end
end
f (a:C1) is
do
a.foo
end
f (create {C2})
==> 2 " As C2 does not define a foo, this may be surprising..."
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
in f() foo is sent to a subtype of C1, but C2 does not have 'foo'!
But it is still lookup because the compiler knows that foo was
renamed in bar.
This is still a simple example. Things become very complicated with
the ((in)famous) diamond pattern. Ambiguities need to be resolved
with a dedicated keywords, 'select'. For example:
Let's assume 4 classes, C1, C2, C3, C4.
C1 defines a feature f.
C2 inherits from C1, and redefine f as 'print (A)'
C3 inherits from C3 and redefine f as 'print(B)'
C4 inherits from C2 and C3.
If you have:
c: C1
create {C4} c
c.f
==> Ambiguity!!!
Because two different paths are possible (C1, C2, C4 and C1, C3, C4).
This needs a 'select' to remove the ambiguity.
For instance, if C3 is defined as:
C4 inherit C3
rename
f as g
select
g
end
then:
c: C1
create {C4} c
c.f
==> B
Not trivial to determine it without being expert in Eiffel...
Cheers,
Alexandre
--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel http://www.cs.tcd.ie/Alexandre.Bergel
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
More information about the Squeak-dev
mailing list
|