Julia is a fast-growing language and with each generation, new capabilities unveiled and some Q&As need review.
IMPORTANT
julia> VERSION
v"0.6.0-dev.2259"
One of the advanced features of Julia is its dispatching system.
(excellent reading about multiple dispatch).
Now, because of this merge (v0.6.0 2017-1-16) users could benefit from new capability of triangular dispatching (read why is it useful?).
Here we need to address the problem of writing generic methods for two arguments:
- A one dimensional array (general vector) of numbers
w
- A general array of general vectors of numbers
x
@wallnuss's answer involves 4 methods that all work. Here is the first one:
function meanw{T <: Number}(x::Array{Vector{T}, 1}, w::Vector{T})
info("both are Vector for the same element-type: $T")
end
julia> meanw([[1],[2]], [1])
INFO: both are Vector for the same element-type: Int32
The above is very specific mainly because it doesn't cover different sub types of AbstractVector
e.g.:
julia> (typeof(spzeros(3)) |> supertype |> supertype) <: AbstractVector #=> true
So the second one is defined:
function meanw{T <: Number}(x::Array{Vector{T}, 1}, w::AbstractVector{T})
info("an Array of Vectors and an AbstractVector sub-type both with the same element-type: $T") #
end
With the above:
julia> meanw([[1.],[2]], spzeros(3))
INFO: an Array of Vectors and an AbstractVector sub-type both with the same element-type: Float64
And a more general method:
function meanw{T <: Number}(x::AbstractArray{Vector{T}, 1}, w::AbstractVector{T})
info("an AbstractVector subtype of Vectors and an AbstractVector sub-type both with the same element-type $T")
end
Even after the latest method, some scenarios isn't fulfilled:
julia> meanw([spzeros(3) for i=1:3], spzeros(3)) #=> Error
julia> meanw([[1],[2]],[1.]) #=> Error
So all the above are more specific than may need.
function meanw{T <: Number, V <: AbstractVector}(x::AbstractArray{V, 1}, w::AbstractVector{T})
info("an AbstractVector of AbstractVector sub-type with Any element and an AbstractVector sub-type of Number")
end
Seems that the last method covers all possible scenarios, but it is more general than may need e.g.:
julia> meanw([[""],[2]],[1.]) #=> Not enough restriction for element type of first AbstractVector
INFO: an AbstractVector of AbstractVector sub-type with Any element and an AbstractVector sub-type of Number
Now with the new triangular feature we could write:
function meanw{T <: Number, V <: AbstractVector{T}}(x::AbstractArray{V, 1}, w::AbstractVector{T})
info("an AbstractVector of AbstractVector sub-type and an AbstractVector subtype both for same sub-type of Number (triangular)")
end
Check methods precedence:
julia> methods(meanw)
# 5 methods for generic function "meanw":
meanw{T<:Number}(x::Array{Array{T,1},1}, w::Array{T,1}) in Main at REPL[1]:2
meanw{T<:Number}(x::Array{Array{T,1},1}, w::AbstractArray{T,1}) in Main at REPL[22]:2
meanw{T<:Number}(x::AbstractArray{Array{T,1},1}, w::AbstractArray{T,1}) in Main at REPL[24]:2
meanw{T<:Number,V<:AbstractArray{T<:Number,1}}(x::AbstractArray{V,1}, w::AbstractArray{T,1}) in Main at REPL[41]:2
meanw{T<:Number,V<:(AbstractArray{T,1} where T)}(x::AbstractArray{V,1}, w::AbstractArray{T,1}) in Main at REPL[39]:2
The latest method have taken the 4th seat because it is more specific that its former.
julia> meanw([spzeros(3) for i=1:3], spzeros(3))
INFO: an AbstractVector of AbstractVector sub-type and an AbstractVector subtype both for a same sub-type of Number (triangular)
But meanw([[2],[2]],[1.])
is still directed to the more general method (5th). Let define another method:
function meanw{T <: Number, W <: Number, V <: AbstractVector{W}}(x::AbstractArray{V, 1}, w::AbstractVector{T})
info("an AbstractVector of AbstractVector sub-type and an AbstractVector sub-type both for Number (triangular)")
end
julia> meanw([[2],[2]],[1.])
INFO: an AbstractVector of AbstractVector sub-type and an AbstractVector sub-type both for Number (triangular)