4 ms·
In the last few months I've been drifting toward the idea that parametric polymorphism is in fact enough for everything, and subtype polymorphism isn't needed a
by cousin_it 12y ago
In the last few months I've been drifting toward the idea that parametric polymorphism is in fact enough for everything, and subtype polymorphism isn't needed at all. If you have subtype and parametric polymorphism in the same language, designing software becomes way too complicated. For example, look at this bullshit:
public static <T extends Comparable<? super T>> void sort(List<T> list)
There's no good reason why a simple concept, like sorting, must have a hugely complicated type that involves inheritance, F-bounded polymorphism and wildcards. It should be replaced with this:
public static <T> void sort(List<T> list, Comparator<T> comparator)
You can use that idea to replace pretty much all uses of subtype polymorphism with parametric polymorphism. The notion of interface inheritance, like "inheriting from" the interface Comparator<T>, is also unnecessary, because you can use a record type containing first-class functions instead. I wrote it up in more detail here: http://lambda-the-ultimate.org/node/4950 http://lambda-the-ultimate.org/node/4950
- seabee 12y agoThat was the goal of the C++ STL. Some may argue it goes too far, other opinions suggest it doesn't go too far enough; however I think most people can agree that you need typeclasses/traits/concepts et al. if you don't want to be doomed to passing different data structure manipulation functions to every call, as in your replacement example, or else resort to underspecifying the requirements of your type parameters and experiencing compiler messages from Hell.
- cousin_it 12y agoI'm hoping that some system like Scala's implicit arguments or Agda's instance arguments could ease the burden of passing stuff around. I don't know if that's enough for most realistic use cases, though. There's another complication. For operations that make sense on only some types, it makes sense to pass around the implementation of the operations, because it also acts as a type constraint. But for operations that make sense on all types, like Java's equals/hashCode/toString (and possibly also comparison), I suppose it's better to make them overridable for each type, as a special case in the language.
- danieldk 12y agoIn the last few months I've been drifting toward the idea that parametric polymorphism is in fact enough for everything, and subtype polymorphism isn't needed at all. Also relevant reading in this context: Haskell Antipattern: Existential Typeclass http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/ http://lukepalmer.wordpress.com/2010/01/24/haskell-antipatte...