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