Le mardi 29 avril 2014 à 11:51 -0400, Stefan Karpinski a écrit :
[...]
> 1.
>
> The explicit distinction between A – the actual parameter type of x –
> and B, which is simply an upper bound on A, becomes clearer in
> situations like this:
>
>
> frob{A<:B}(x::P{A}, y::A)
> frob{A<:B}(x::P{A}, y::B)
>
>
> The first definition only applies to x and y where y is of the actual
> parameter type of x and thus could be used as is by x. The second
> definition applies when y is of type B, regardless of x's actual
> parameter type, which means that it might not be usable as is by x.
>
>
> We could actually make parametric types covariant without losing the
> ability to express this distinction; it would just mean that the
> second definition could be written as:
>
>
> frob(x::P{B}, y::B)
>
>
> Currently, this means that x must have exact parameter type B; if
> types were covariant then it would mean that x's parameter type could
> be any A <: B. Although it may seem questionable that y not be of the
> true parameter type of x, allowing this wiggle room and then doing
> conversion at run-time as necessary is actually the standard way to do
> things in Julia. Conversion is often done implicitly by assignment to
> a type location such as a field of x or an array slot. The fact that
> this is quite common is why covariance might actually be ok. The main
> thing we would lose with parametric covariance is the ability to talk
> about arrays that are of *exactly* element type B where B is some
> abstract type. But I'm just not sure how useful that actually is.
> Those types are generally discouraged in any case and it's rare to
> want to give them special behaviors that wouldn't also apply to
> parametric types with concrete parameters. So perhaps we ought to
> consider making parametric types in Julia covariant.
I am very sympathetic to such as change, but one reason why making e.g.
frob(x::Array{B, 1}, y::B) be equivalent to frob{T<:B}(x::Array{T, 1},
y::B), B being abstract, would be a problem, is that the function code
couldn't rely on the assumption that the x vector can hold any value of
type B. Indeed, x could be either an Array{B, 1} or an Array{T, 1} with
T any concrete type as long as T<:B.
Cf. https://github.com/JuliaLang/julia/issues/6248#issuecomment-38435635
(and the following discussion)
In practice, I really don't think this would matter in many occasions.
So maybe it would be a good change, if there was a syntax to specify
that the function really expects an Array{B, 1}. Or maybe the latter
isn't even useful as the function can always call convert() if it's
really needed (can we find use cases for it).
I believe this detail is one of the (quite rare) frustrating points when
one starts coding in Julia. So it would be worth investigating for
Julia's coming success.