As for ML functors: they're neither polymorphism, nor dynamic dispatch. First: functions for different types can't share names (unless we're talking about shadowing of names with lexical scope), the names are either qualified with the name of the struct they come from or they're not qualified at all. In all cases there is exactly one implementation for every name. And again: no dynamic dispatch. MLton even defunctorizes all code at compile-time. The only polymorphism in SML is the one that's used in some built-ins (like +), but it's not available to users of the language. SML has something called "polymorphic functions", but it has nothing to do with writing multiple implementations of one function under one name and letting the compiler select which one is called; which is what is usually meant by "polymorphism".