Method MD: subclass of a class from another module matches untyped overload
Summary
When a method has both an untyped overload and typed overloads on a parent class, and the argument’s class is a subclass defined in a different module than the method, multiple dispatch incorrectly selects the untyped overload.
- Same overload set as free functions: correct (typed parent).
- Method + subclass in the same module/file: correct.
- Method in module A, subclass in module B (or main after
import A): wrong (untyped).
- Instance of the parent class itself: still correct on the method.
Environment
Expected
Closest typed match wins. For class Sub is Scene {} and
open(commands) { ... } // untyped
open(Graphics g) { ... }
open(Scene g) { ... }
receiver.open(Sub()) should return / run open(Scene).
Actual
receiver.open(Sub()) runs open(commands) (untyped).
receiver.open(Scene()) still correctly runs open(Scene).
Minimal example
receiver.morpho (module):
import xgraphics // or whatever module defines Scene / Graphics
class Receiver {
open(commands) { return "untyped" }
open(Graphics g) { return "Graphics" }
open(Scene g) { return "Scene" }
}
Driver (separate file / REPL after import):
import receiver
import xgraphics
class Sub is Scene {}
var r = Receiver()
print(r.open(Scene())) // Scene (OK)
print(r.open(Sub())) // untyped (BUG — should be Scene)
print(r.open("hi")) // untyped (OK)
/* Free functions with the same signatures are fine */
fn f(commands) { return "untyped" }
fn f(Graphics g) { return "Graphics" }
fn f(Scene g) { return "Scene" }
print(f(Sub())) // Scene (OK)
Same-file control (no bug):
import xgraphics
class Receiver {
open(commands) { return "untyped" }
open(Graphics g) { return "Graphics" }
open(Scene g) { return "Scene" }
}
class Sub is Scene {}
print(Receiver().open(Sub())) // Scene (OK)
Impact
Any API like View.open(Scene) that also has an untyped open(commands) break for user subclasses defined outside the module that declares View (e.g. class Plot is Scene in another package). Call sites such as View(plot) then pass the object into the string/command path and fail later.
Workaround
Type the catch-all overload:
open(String commands) { ... }
so a Scene subclass cannot match it; dispatch then selects open(Scene).
Method MD: subclass of a class from another module matches untyped overload
Summary
When a method has both an untyped overload and typed overloads on a parent class, and the argument’s class is a subclass defined in a different module than the method, multiple dispatch incorrectly selects the untyped overload.
importA): wrong (untyped).Environment
Expected
Closest typed match wins. For
class Sub is Scene {}andreceiver.open(Sub())should return / runopen(Scene).Actual
receiver.open(Sub())runsopen(commands)(untyped).receiver.open(Scene())still correctly runsopen(Scene).Minimal example
receiver.morpho(module):Driver (separate file / REPL after import):
Same-file control (no bug):
Impact
Any API like
View.open(Scene)that also has an untypedopen(commands)break for user subclasses defined outside the module that declaresView(e.g.class Plot is Scenein another package). Call sites such asView(plot)then pass the object into the string/command path and fail later.Workaround
Type the catch-all overload:
so a
Scenesubclass cannot match it; dispatch then selectsopen(Scene).