Sorry, maybe I'm misreading your comment, but are you saying that julia doesn't have parameterized types? If so, that's untrue, but maybe you're saying Dylan doesn't have parameterized types? It's a little unclear in the text.
> The parameterising complicates the subtyping relationships needed to specify how multiple dispatch works.
I don't think it adds all that much complication actually, and it adds a ton of extra expressive power. For instance, our arrays are parameterized by their element type and their dimensionality, so
Array{Int, 1}
is a 1D (vector) array of Ints whereas
Array{Complex{Float64}, 2}
is a 2D (matrix) of Complex Float64s. This is really important for making the most of multiple dispatch imo because I can write methods which take advantage of as much type information as possible. This isn't just helpful for performance, but also helpful for just expressing your algorithm in a clear and general way.
When I last wrote Julia I think it was unclear to me how subtyping worked with type parameters, or writing type specifiers for methods was complicated by them. I think all type constructors are invariant, so you couldn’t have T{X} < T{Y} unless X = Y (but I think you can have a rule like S{X} < T{X}). This makes sense in some cases as covariance or contravariance don’t work for arrays (suppose I want an Animal array but you give me a Dog array, then when I read elements I get Animals as expected but if I were to try to write a Cat there, it would be bad. Java has this rule and will throw a runtime extension in the case described), but it can work for immutable types, though Julia can’t enforce that all subtypes are immutable and type parameters needn’t be types anyway.
> The parameterising complicates the subtyping relationships needed to specify how multiple dispatch works.
I don't think it adds all that much complication actually, and it adds a ton of extra expressive power. For instance, our arrays are parameterized by their element type and their dimensionality, so
is a 1D (vector) array of Ints whereas is a 2D (matrix) of Complex Float64s. This is really important for making the most of multiple dispatch imo because I can write methods which take advantage of as much type information as possible. This isn't just helpful for performance, but also helpful for just expressing your algorithm in a clear and general way.