The context here is, “I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type.”
As I understand it, he's saying that, in languages like Smalltalk, the method that gets invoked for a particular message is determined by the type of the receiver only, not by the types of all the arguments. This is also true of, for example, Java before generics. By contrast, consider what you need to do for multiplication and division in a world containing integers Z, rationals Q, and floats R. Multiplication maps (Z,Z) to Z; (Z,Q), (Q,Z), and (Q,Q) to Q; and everything else to R. Division maps (Z,Z), (Z,Q), (Q,Z), and (Q,Q) to Q (Python 3 notwithstanding) plus division by zero; and everything else to R. In particular, note that if an integer is the "receiver" of a multiplication message, it may need to invoke the integer multiplication algorithm, the rational multiplication algorithm, or the float multiplication algorithm, and the return type will vary similarly.
In dynamically typed languages you can just resort to double dispatch in cases like this, but if you are trying to statically compute the type of the inner product of an integer vector and a rational vector (from the type signature of the inner-product operator), things are a bit more difficult.
CLOS and Dylan do have multiple dispatch for cases like this.
But Stepanov’s generic programming work is not primarily about so-called ad-hoc polymorphism, but about the other kind, parametric polymorphism. You want to be able to say things like, “Given a vector type V, its corresponding scalar type S has a multiplication operator S·V returning V,” and ideally give a generic specification from which efficient implementations of the operation can be automatically produced for any concrete vector type.
I believe that the distinction that Stepanov is alluding to is the distinction between intensional and extensional types.[1]
> Of course, that's exactly what Alan Kay says
I'm not sure what Alan Kay says. Your post could be improved by providing a reference or quote so that I can read Alan Kay's take. Note that to varying degrees both C++ and Haskell allow for intensionality without resorting to dynamic types.
As I understand it, he's saying that, in languages like Smalltalk, the method that gets invoked for a particular message is determined by the type of the receiver only, not by the types of all the arguments. This is also true of, for example, Java before generics. By contrast, consider what you need to do for multiplication and division in a world containing integers Z, rationals Q, and floats R. Multiplication maps (Z,Z) to Z; (Z,Q), (Q,Z), and (Q,Q) to Q; and everything else to R. Division maps (Z,Z), (Z,Q), (Q,Z), and (Q,Q) to Q (Python 3 notwithstanding) plus division by zero; and everything else to R. In particular, note that if an integer is the "receiver" of a multiplication message, it may need to invoke the integer multiplication algorithm, the rational multiplication algorithm, or the float multiplication algorithm, and the return type will vary similarly.
In dynamically typed languages you can just resort to double dispatch in cases like this, but if you are trying to statically compute the type of the inner product of an integer vector and a rational vector (from the type signature of the inner-product operator), things are a bit more difficult.
CLOS and Dylan do have multiple dispatch for cases like this.
But Stepanov’s generic programming work is not primarily about so-called ad-hoc polymorphism, but about the other kind, parametric polymorphism. You want to be able to say things like, “Given a vector type V, its corresponding scalar type S has a multiplication operator S·V returning V,” and ideally give a generic specification from which efficient implementations of the operation can be automatically produced for any concrete vector type.