Multiple polymorphism / multi-methods

Mario Wolczko mario at
Sat Mar 23 13:09:55 UTC 1991

>From the burst of messages on this subject, it's clear that there is
interest in having multi-methods, but some reservations also.
I think this area is ripe for experimentation: there are lots of
contending schemes, and no clear winner.  Because of this, I suggest
making the whole area open to user experimentation, rather than fixing
on one solution.  Then, in the light of experience, a winner may

This is the approach I have taken in the design of MUST, an (as yet
unimplemented) Smalltalk-like language.  I would suggest that the
method lookup routine be written *within the language*.  Given modern
method-caching technology, a full-blown method lookup is rarely
invoked, and the resulting small drop in performance should be

The existing method lookup logic in Smalltalk-like languages looks
(conceptually) something like this (apologies for the Smalltalk; I'm
not fluent in Self): 

	findMethod: selector for: object args: argArray
	  (methodDictionary includes: selector)
	     ifTrue: [^methodDictionary at: selector]
	  superclass isNil
	     ifTrue: [^object perform: #doesNotUnderstand
	     		     with: Message
			     selector: selector
			     args: argArray]
	  ^superclass findMethod: selector for: object args: argArray

The scheme in MUST works like this: conceptually, whenever a message
is sent to an object, a reflection takes place to a higher level
resulting in the findMethod: message being sent to the object (just as
the doesNotUnderstand is sent in the failure case).  The default
definition would be as above.  However, the user if free to override
this and return a method of his own choice.  Of course, when the
method is returned, the resulting combination of keys and method is
entered into a cache, which is consulted thereafter.

This could be used to experiment with multiple inheritance,
multimethods, protection schemes, etc.

There are two possible problems to be overcome:
1. Because the lookup method can be an arbitrary algorithm, the cache
   may not be sufficiently flexible to hit often enough, despite some
   lookup schemes being very simple.  Making it more flexible is
   likely to make is slower.  The tradeoffs are worth investigating.
2. Lookup routines should be purely functional (ie always return
   the same result for the same input), otherwise the cache could hold
   the wrong value.  Likewise, the compiler, which would invoke this
   routine when attempting to perform static binding, would get the
   wrong answer.  It seems unlikely that this could be checked
   automatically.  However, "With freedom comes responsibility"  :-).

Mario Wolczko

   ______      Dept. of Computer Science   Internet:      mario at
 /~      ~\    The University              uucp:      mcsun!ukc!man.cs!mario
(    __    )   Manchester M13 9PL          JANET:         mario at
 `-':  :`-'    U.K.                        Tel: +44-61-275 6146  (FAX: 6280)
____;  ;_____________the mushroom project___________________________________

More information about the Self-interest mailing list