Use C3 linearization for multimethod dispatch
Gattag opened this issue · comments
Procedure: Method Dispatch
-
Compute the call signature:
- Let M be the set of all methods.
- Let mcs be the method referenced at the call-site.
- Let scs be the signature of mcs.
- Let sa be the type signature of the arguments at runtime.
- The call signature s is obtained by substituting
null
arguments in sa with the corresponding parameter types from scs.
-
Collect methods that match the call-site method’s name and number of arguments and have a supertype signiture of the :
- Let M′ = {m ∈ M ∣ name(m) = name(mcs) ∧ numArgs(m) = numArgs(mcs) ∧ signature(m) :≥ s}.
-
If M′ is empty, throw an exception as there are no dispatchable
methods.- This condition may occur only when the method is called reflectively.
-
Reduce the set to methods that are not supertypes of any other method in the set, these are the most specific signatures:
- Let M″ = {m ∈ M′ ∣ ∀n ∈ M′ ∣ ¬(signature(m):>signature(n))}.
-
At this point, M″ will have at least one member.
- If |M″| = 1, dispatch to the single method in M″.
-
If |M″| > 1, resolve ambiguity using a modified C3 linearization (the MPS variant) with precedence for arguments left to right.
- Apply the modified C3 linearization algorithm to order the methods in M″ and determine the most preferred method for dispatch.
-
At this point, the algorithm will always produce one most preferred method to dispatch to.
TODO formalize C3 and left to right precedence