Revisited : passing and returning arrays with unspecified type

I had previously asked how to pass arrays of unspecified type as input to a function, to which I had got a nice solution using where T. Hoewever, I am having a problem when trying to specify the output type as an Array of unspecified type.
For example see the following function which accepts a matrix and vector and returns their vector. I am purposefully not using AbstractMatrix or AbstractVector as I eventually will work with higher dimensional arrays.

function ff( A::AbstractArray{T1, 2} where T1, x::AbstractArray{T2, 1} where T2) ::AbstractArray{T,1} where T
    y = A*x;
    return y;
end

I am getting the following error :

julia> include("t.jl");
julia> TM1 = rand(Int64, 4,3); tv1 = rand(Float64, 3); ff(TM1, tv1)
ERROR: UndefVarError: T not defined
Stacktrace:
 [1] ff(::Array{Int64,2}, ::Array{Float64,1}) at C:\ShobKichhu\Julia\t.jl:2
 [2] top-level scope at none:0

You just need one more set of parentheses to ensure that AbstractArray{T, 1} where T is parsed as the return type, rather than trying to apply the where T to the entire function definition:

julia> function ff( A::AbstractArray{T1, 2} where T1, x::AbstractArray{T2, 1} where T2)::(AbstractArray{T,1} where T)
           y = A*x;
           return y;
       end
ff (generic function with 1 method)

julia> ff(zeros(2, 2), zeros(2))
2-element Array{Float64,1}:
 0.0
 0.0

It’s also worth noting that the return type annotation will probably have no performance benefit at all, particularly since it’s an abstract type. If it helps you organize and document your code, then that’s totally fine, but you can safely remove it if it makes your life harder.

3 Likes

I see ! Thanks.
So you mean that if I just wrote
function ff() :: AbstractArray
it would be the same in terms of performance ? Can I specify just the output array dimension, such as AbstractArray{1} ?

I mean that if you did ff() or ff()::AbstractArray or ff::(AbstractArray{T, 1} where T) you would get the same performance for any of those.

That’s exactly what (AbstractArray{T, 1} where T) is, and that’s also exactly what AbstractVector is:

julia> AbstractVector === (AbstractArray{T, 1} where T)
true

Yes, you showed me AbstractVector and AbstractMatrix before. As I mentioned in this post, I intend to write code that return a 3D matrix. So I guess AbstractArray{3} wont work ? I either not mention the type at all, or mention both the eltype and dimension