Musing on PMD dispatch problems

Jecel Assumpcao Jr jecel at merlintec.com
Fri Jun 6 16:47:19 PDT 2003


On Tuesday 03 June 2003 20:32, Lee Salzman wrote:
> Well, that full ordering makes a lot more sense than the current one,
> and is exactly the one that CLOS uses, leftmost argument positions
> have higher precedence than rightmost.
>
> This was ideally how PMD should have behaved in the first place, but
> didn't quite because of these weird ambiguities. :)

This makes me think that it might be possible to make the compiler 
transform these multiple dispatch methods into several single dispatch 
ones so I can run this on my single dispatch hardware...

Looking through the code it seems that one in four method declarations 
are multiple dispatch. I don't know what the dynamic frequency would 
be. As an example of my idea, I found 15 implementations of "+" in a 
quick scan of my obsolete copy of Slate:

arrayed.slate:a1@(NumericArrayMD traits) + a2@(NumericArrayMD traits)
dimensioned.slate:x@(UnitValue traits) + y@(UnitValue traits)
matrix.slate:a@(AbstractMatrix traits) + b@(AbstractMatrix traits)
matrix.slate:mat@(AbstractMatrix traits) + x@(Magnitude traits)
matrix.slate:x@(Magnitude traits) + mat@(AbstractMatrix traits)
numeric.slate:x@(Fraction traits) + y@(Integer traits)
numeric.slate:x@(Integer traits) + y@(Fraction traits)
numeric.slate:x@(Fraction traits) + y@(Fraction traits)
numericMixin.slate:t@(NumericMixin traits) + n@(Number traits)
numericMixin.slate:t@(NumericMixin traits) + u@(NumericMixin traits)
time.slate:t1@(Time Time traits) + t2@(Time Time traits)
time.slate:d1@(Time Duration traits) + d2@(Time Duration traits)
time.slate:i@(Time Instant traits) + d@(Time Duration traits)
graphics/layout.slate:sr1@(SpaceRequirement traits) + 
sr2@(SpaceRequirement traits)

Another quick scan shows these inheritance relations:

NumericArrayMD:ArrayMD:Collection":Cloneable"
UnitValue:Magnitude:Cloneable
AbstractMatrix:Cloneable
Fraction:Number, Cloneable traits
Integer:
NumericMixin:Mixin:Cloneable
Time:Magnitude:Cloneable
Duration:Magnitude:Cloneable
Instant:Magnitude:Cloneable
SpaceRequirement:Object

How odd... I couldn' find where Integer, Number and Object are defined. 
It doesn't matter since there are probably lots of mistakes in what 
follows.

A compiler could rewrite the above as:

a1@(NumericArrayMD traits) + a2
[ a2 md1: a1
]

a2@(NumericArrayMD traits) md1: a1
[ "same code as NumericArrayMD traits + NumericArrayMD traits"
]
"--------------------"
x@(UnitValue traits) + y
[ y md2: x
]

y@(UnitValue traits) md2: x
[ "same code as UnitValue traits + UnitValue traits"
]
"--------------------"
a@(AbstractMatrix traits) + b
[ b "x" md3: a "mat"
]

b@(AbstractMatrix traits) md3: a
[ "same code as AbstractMatrix traits + AbstractMatrix traits"
]

x@(Magnitude traits) md3: mat
[ "same code as AbstractMatrix traits + Magnitude traits"
]
"--------------------"
x@(Magnitude traits) + mat
[ mat md4: x
]

mat@(AbstractMatrix traits) md4: x
[ "same code as Magnitude traits + AbstractMatrix traits"
]
"--------------------"
x@(Fraction traits) + y
[ y md5: x
]

y@(Integer traits) md5: x
[ "same code as Fraction traits + Integer traits"
]

y@(Fraction traits) md5: x
[ "same code as Fraction traits + Fraction traits"
]
"--------------------"
x@(Integer traits) + y
[ y md6: x
]

y@(Fraction traits) md6: x
[ "same code as Integer traits + Fraction traits"
]
"--------------------"
t@(NumericMixin traits) + n
[ n "u" md7: t
]

n@(Number traits) md7: t
[ "same code as NumericMixin traits + Number traits"
]

u@(NumericMixin traits) md7: t
[ "same code as NumericMixin traits + NumericMixin traits"
]
"---------------------"


And so on. It seems that the inheritance information isn't needed for 
this kind of transformation. And the debugger would have to be smart in 
order not to show "#md4: not found" on an error, but a more sensible 
message.

Of course, this is just doing automatically what a Smalltalk programmer 
would do by hand (but with better message names ;-) It might seem silly 
to have the Slate programmer organize things all nicely just to have 
the compiler rewrite it as ugly double dispatching, but that is no 
different than using polymorphism well in your source code and having 
the compiler effectively generating a bunch of case statements from 
that (that is all PICs really are).

I found 12 cases of triple dispatching, but the same trick could handle 
them as well (adding two levels of message sends instead of one.

-- Jecel
P.S.: "same code as" above mean same code as in the original version of 
the named method



More information about the Slate mailing list