In my move to Julia one thing that I go back and forth is on the type annotation of function parameters. One particular case is when a function can accept vectors of any type of numbers, but those vectors must be of a specific dimension. A simple example would be a function that computes the distance between points in three-dimensions:*
function dist(x,y)
d = zero(eltype(x))
for i in 1:3
d += (x[i]-y[i])^2
end
sqrt(d)
end
*Of course, in this case, one can write easily the function that does the same for every dimension. But this is not the point, because in my codes I am only dealing with points in 3D space and thus I am referring to every function of my codes, some for which that is simple, some for which that would be cumbersome.
So, my question is: What is the best practice for the type annotation of parameters? Leave it blank (as it is there)?
State at least that they should be vectors:
dist(x::AbstractVector,y::AbstractVector}
Abstract vectors of a given type? AbstractVector{Float64}
, although that would limit the function somehow (the fact that AbstractVector{Real}
does not work is somewhat unintuitive - I understand why is that, but it is unintuitive noneless; edit: should be AbstractVector{T} where T<:Real
to work, wright?).
And, finally, it seems there is no way to declare, at least, that it must be an abstract vector of dimension 3, is it (except if specialized to static arrays, for instance). One thing I already used is
dist(x :: T, y :: T) where T <: MyVectorType
where MyVectorType
is a constant global inside my package which defines the type of data I am using (SVector{3,Float64}
, for example). But than I took it back to most clean forms.
More generally it could be
dist(x :: AbstractVector{T1},y :: AbstractVector{T1}) where {T1, T2 <: Real}
but seems too bloated… and still does not define the length of the vectors, which is themost important.
What are the recommendations here?