# Type declaration in function arguments: Allow adjoints and column vectors?

**URL:** <https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960>\
**Category:** General Usage\
**Tags:** question\
**Created:** [February 10, 2021, 12:58am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960 "2021-02-10T00:58:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [February 10, 2021, 12:58am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/1 "2021-02-10T00:58:46Z")

</div>

I have a function that nominally accepts only 2-dimension arrays as input:

```julia
julia> function foo(x::Array{Float64, 2})
           # Stuff
           return nothing
       end
foo (generic function with 1 method)

julia> y = rand(5, 6)
5×6 Array{Float64,2}:
 0.818613 0.402175 0.141845 0.649995 0.622611 0.432664
 0.368095 0.196203 0.235136 0.657062 0.281461 0.603284
 0.962769 0.335103 0.875451 0.587475 0.620739 0.393967
 0.957616 0.273278 0.740744 0.14692 0.792191 0.779481
 0.95631 0.815702 0.961613 0.49849 0.188148 0.96158

julia> foo(y) # No error

```

But I sometimes want to call this function on the transpose of an array. This doesn’t work:

```julia
julia> foo(y')
ERROR: MethodError: no method matching foo(::LinearAlgebra.Adjoint{Float64,Array{Float64,2}})
Closest candidates are:
  foo(::Array{Float64,2}) at none:1
Stacktrace:
 [1] top-level scope at none:1

```

Instead, I have to do

```julia
julia> foo(permutedims(y)) # No error

```

Likewise, sometimes my array is just a column vector, and in such cases I would like it to be treated as a 2D array whose second dimension is `1`:

```julia
julia> z = rand(5)
5-element Array{Float64,1}:
 0.373288007992006
 0.971884387492479
 0.8786393449999188
 0.9435088229078494
 0.570539122742798

julia> foo(z)
ERROR: MethodError: no method matching foo(::Array{Float64,1})
Closest candidates are:
  foo(::Array{Float64,2}) at none:1
Stacktrace:
 [1] top-level scope at none:1

julia> foo(reshape(z, 5, 1)) # No error

```

Now, I understand that I can explicitly allow adjoints and column vectors by modifying the function like so:

```julia
using LinearAlgebra

function foo(x::Union{Array{Float64,2},
                      Adjoint{Float64,Array{Float64,2}},
                      Array{Float64,1}})
    if typeof(x) == Array{Float64,1}
        x = reshape(x, :, 1)
    end
    return nothing
end

```

(In my real function, there are loops over both dimensions of `x`, so the reshaping is necessary.)

But this is unsightly, and I am wondering if there is a better way to do this. **Is there a type declaration that is equivalent to the following statement?**

- “`x` should be an 2-dimensional array, or something that can be unambiguously interpreted as such”

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [February 10, 2021, 1:11am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/2 "2021-02-10T01:11:16Z")

</div>

What is happening is that you are restricting `foo` to only accept `Array{Float64, 2}` types. The output of `y'` is not `Array{Float64, 2}`. Perhaps you should define `foo` to accept a subtype of `DenseArray`, `AbstractArray` or do not specify any type at all. Or take a look at Parametric Types and Parametric Methods in the documentation to specify your last condition.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [February 10, 2021, 1:18am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/3 "2021-02-10T01:18:24Z")

</div>

To expand upon the previous answer, usually you want to leave the argument types as generic as possible. So, in this case something like the following might be a good option:

```julia
function foo(x::AbstractArray{T, 2}) where T
    return 1
end

function foo(x::AbstractVector{T}) where T
    return foo(reshape(x, :, 1))
end

```

You can put a type constraint on `T` if you need the entries to be real numbers:

```julia
function foo(x::AbstractArray{<:Real, 2})
    return 1
end

function foo(x::AbstractVector{<:Real})
    return foo(reshape(x, :, 1))
end

```

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [February 10, 2021, 5:39am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/4 "2021-02-10T05:39:03Z")

</div>

Thank you both for the helpful responses. I have been playing around with types and I am having trouble wrapping my head around this:

```julia

julia> Float64 <: Real
true

julia> Array{AbstractFloat, 1} <: AbstractArray{Real, 1}
false

```

What is the intuition behind this? To me, it seems like if `Float64` is a subtype of `Real`, and `Array` a subtype of `AbstractArray`, then the second statement should hold.

Edit: The solution is to use

```julia
julia> Array{AbstractFloat, 1} <: AbstractArray{<:Real, 1}
true

```

I guess the `<:` operator doesn’t “distribute” to the inside of the braces.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 10, 2021, 6:30am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/5 "2021-02-10T06:30:46Z")

</div>

Julia types are invariant on their type parameters. That means, `T<:S` implies neither `Vector{T} <: Vector{S}` nor `Vector{T} >: Vector{S}`.  
Rationale: `Vector{Real} <: Vector{Number}` makes sense only if we consider vectors as values. “An iterable which produces real values” is a kind of “an iterable which produces numeric values”. But vectors can also be viewed as containers. “A container which can store any real value” is not a kind of “a container which can store any numeric value”. In fact, the opposite holds: anywhere a `Vector{Real}` is suitable as a container, a `Vector{Number}` must be as well. That leads to conclusion that neither of `Vector{Real}` and `Vector{Number}` can be viewed as a supertype of another.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [February 10, 2021, 6:37am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/6 "2021-02-10T06:37:12Z")

</div>

OK, I think I’m getting this. So `S <: T & VectorA <: VectorB` implies `VectorA{S} <: VectorB{<:T}`, and does the converse hold as well?

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [February 10, 2021, 6:44am UTC](https://discourse.julialang.org/t/type-declaration-in-function-arguments-allow-adjoints-and-column-vectors/54960/7 "2021-02-10T06:44:40Z")

</div>

Yes, that holds.
