4 ms·
No. ML functors are about parametric polymorphism, classes are about subtype polymorphism. There are some inherent similarities between the two, but also some d
by rbehrends 10y ago
No. ML functors are about parametric polymorphism, classes are about subtype polymorphism. There are some inherent similarities between the two, but also some differences that are non-trivial to reconcile (such as early vs. late binding). C++ templates come close, but that's because they also are about parametric polymorphism, not classes as such.
ML functors are modules that are parameterized by other modules. A common use case is that the parameter module contains several types and the logic for their interaction. Unless you've got sufficiently expressive virtual types or an equivalent mechanism (C++ templates), you won't be able to approximate that with inheritance alone.
Scala in some ways approximates the expressive power of ML functors, but at the expense of being hugely more complicated. One of the virtues of ML functors is that they are fairly straightforward, both in terms of use and implementing them in a compiler.
- saosebastiao 10y agoBut classes are capable of both parametric polymorphism AND subtype polymorphism. For example, compare `class FooFunctor[T <: FooSig](arg: T)` to `module FooFunctor (arg: FooSig)`. Aren't those equivalent? What do you mean by late binding vs early binding?
- rbehrends 10y agoFirst, the parametric polymorphism mechanisms in most OO languages are orthogonal to the concept of classes. Second, as I said, try it with multiple types that are interdependent. Once you do that, you go down the rabbit hole of higher-kinded and existential types to make sure that everything lines up properly with the compiler's inference mechanisms. A key difference is that the generics in most OO languages allow you to parameterize only by types. An ML functor makes the parameter a module. Everything you can stuff in a module can be part of the parameter signature, and you can create whatever relationships you need between them. And you can do things such as hash tables with both case-sensitive and case-insensitive string keys that still share the same string type. Finally, in your Scala example, keep in mind that unlike ML functors, it has the usual constructor problem that many simple genericity mechanisms have: constructing instances of the parameter type. In Scala, that means you end up working with CanBuildFrom or implicit arguments; C# and Eiffel have specialized (and ultimately, still less flexible) language constructs to deal with that.
- milesrout 10y ago>Finally, in your Scala example, keep in mind that unlike ML functors, it has the usual constructor problem that many simple genericity mechanisms have: constructing instances of the parameter type. In Scala, that means you end up working with CanBuildFrom or implicit arguments; C# and Eiffel have specialized (and ultimately, still less flexible) language constructs to deal with that. What does C++ have? Or what do those languages not have? Do they not work the same way as C++, where you can just write: auto t = T{args...}; ?
- rbehrends 10y agoTemplates in C++ are basically macros and can do a lot more as a result (and that comes with the usual costs, such as your code size potentially blowing up, getting in the way of separate compilation, and the problems with enforcing constraints on parameters; concepts have yet to make it into the language). It's totally different from languages where parametric polymorphism is part of the type system proper.
- milesrout 10y agoTemplates in C++ are not 'basically macros' in the C++ sense.