Martin, again this may be an annoying digression for some people on the Revisiting Implicits thread, and anything I say about type classes is probably wrong, as I really don’t understand them. I’m still struggling. But the few times I’ve implemented one (with help of experts) it reminds me meta-programming in Lisp.
To me it seems a type class is a mechanism for specifying that a certain set of types need to behave a certain way. I.e., extend the behaviour of a set of classes. In CLOS I’d extend the behaviour of a set, X, of classes by defining a meta class, M, which implements that behaviour, and arranging that each of the classes in X designate M as its meta class.
For example, normally instance slot access is done through some sort of array look-up which is predicted at compile time. However, if I want slot-access of class C to always read/write from a persistant database, I’d implement the behaviour in a meta class it as C’s meta class. For example, I’d override the get-slot-value and set-slot-value methods in the meta class.
Another example is if don’t like the order of the default CLOS class precedence list which (unlike Scala) does not allow two parent classes to inherit from the same grand-parent classes in conflicting orders. I could implement this by providing a new meta-class where I overriding the compute-class-precedence method.
In Scala, a limitation (motivated by its Java heritage) is that I cannot add methods to classes I don’t own. So to get around this limitation, I need to implement a type class which effectively intervenes in the method dispatch procedure and trampolines the method call to some other class which I do own. In CLOS this method dispatch procedure is partially predicted at compile time, and refined at run-time. In Scala, the dispatch procedure is 100% baked in at compile time (as I understand).