Given that functions f, g, and h all work, why isn’t function i allowed?
Shouldn’t i work like an alias for g just like h does?
x = 1
y = 0.1
function f(x::Number, y::Number)
return "This is function f."
end
function g(x::T1 where T1<:Number, y::T2 where T2<:Number)
return "This is function g."
end
function h(x::Vector{<:Number}, y::Vector{<:Number}) # Call with h([x], [y])
return "This is function h."
end
function i(x<:Number, y<:Number)
return "This is function i."
end
ERROR: syntax: "x <: Number" is not a valid function argument name
For me (even in reading) it is not clear for this whether you mean that x is a type that inherits from number or a variable of a type that inherits from number.
edit: To be more precise, you could pass x=Float64 in there, which is one way to read your definition, but since it is not clear what you mean (informally reading it for me it does not get clear at least, but the compiler also complains)
I do see two solutions with different goals. You probably meant
function i(x::T, y::S) where {T<:Number, S<:Number}
return "This is function i."
end
that is x and y are some kind of numbers (informally said).
This is basically your g just that the scope of the T and S is a little larger, because you could also do
function i(x::T, y::T) where {T<:Number}
return "This is function i."
end
which would say they are some kind of number, but the same.
Yup, this is the crux – x::T works when x are values, x<:T works for types x (of course any x can be both a value and type, but the operator gives context then). Function arguments are always treated as values, so you can’t <: them.
I’m starting to get it. f just doesn’t seem like it should work to me. x is not a Number it is an Int which is a subtype of Number. Thus I want to indicate that with x<:Number just like in h.
Also, DNF showed that you have to explicitly write Type whenever you want to operate on types themselves, so the type vs value argument seems clear regardless.
function k(x::Vector{MyType{T}}) where {T<:Number}
I was a bit surprised, because I though that Vector{MyType{<:Number}} was the same as Vector{MyType{T}} where {T<:Number}. But it turns out to be a tiny bit different:
julia> Vector{MyType{<:Number}} === Vector{MyType{T}} where {T<:Number}
false
julia> Vector{MyType{<:Number}} === Vector{MyType{T} where {T<:Number}}
true
Yes, but why?
What is the full identical equivalence for this form?
I don’t see how that would make a functional difference. The where defines T the same either way, and the where location doesn’t matter in this case from the documentation:
A correct way to define a method that accepts all arguments of type Point{T} where T is a subtype of Real is:
function norm(p::Point{<:Real})
sqrt(p.x^2 + p.y^2)
end
(Equivalently, one could define function norm(p::Point{T} where T<:Real) or function norm(p::Point{T}) where T<:Real; see UnionAll Types.)
Or, more semantically, whether the vector has to contain elements of the same MyType which all are constrained to the same T<:Number, or whether the vector can contain different MyType, possibly with different T (each of which is still constrained to be <:Number).