# Preferred type expression for a vector of vectors

**URL:** <https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891>\
**Category:** New to Julia\
**Created:** [August 4, 2018, 1:20pm UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891 "2018-08-04T13:20:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![suiato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suiato/32/1713_2.png) [@suiato](https://discourse.julialang.org/u/suiato)\
**Post date:** [August 4, 2018, 1:20pm UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/1 "2018-08-04T13:20:21Z")

</div>

Among the expressions below, which one is preferred?

1. x::Vector{Vector{T}} where T\<:Real
2. x::Vector{Vector{T} where T\<:Real}
3. x::Array{Array{T,1},1} where T\<:Real
4. x::Array{Array{T,1} where T\<:Real,1}

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [August 4, 2018, 1:25pm UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/2 "2018-08-04T13:25:57Z")

</div>

1 and 2, and, 3 and 4, are not the same so it depends what behaviour want which is preferable.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [August 4, 2018, 1:52pm UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/3 "2018-08-04T13:52:02Z")

</div>

If you’re storing vectors that all have the same eltype (eg. `Vector{Int}`), then options 1 and 3 are generally preferable for speed reasons, because a nested loop over all elements in all vectors will be type-stable. I would favor 1 over 3 because it’s shorter and cleaner.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 4, 2018, 2:27pm UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/4 "2018-08-04T14:27:31Z")

</div>

> [@cstjean](#):
>
> If you’re storing vectors that all have the same eltype (eg. `Vector{Int}` ), then options 1 and 3 are generally preferable for speed reasons, because a nested loop over all elements in all vectors will be type-stable

If we are talking about argument types for a function declaration, then the type declaration has nothing whatsoever to do with performance or type stability. You get exactly the same performance even if you declare no types at all, because the compiler specializes the function for the whatever argument types are passed.

The question is, what is the poster trying to accomplish by the type declaration here?

---

<div class="post-metadata">

**Author:** ![suiato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suiato/32/1713_2.png) [@suiato](https://discourse.julialang.org/u/suiato)\
**Post date:** [August 5, 2018, 5:02am UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/5 "2018-08-05T05:02:42Z")

</div>

Thank you for comments. As an example, in the program below, `f1(x)` works as expected. `f1(y)` fails, but `f2(y)` succeeds.  
Question 1: Why does `f1(y)` fail?  
Question 2: Why does `f2(y)` succeed?  
Question 3: How can I create an array of type Vector{Vector{T}} where T\<:Real?

When I do typeof(),  
`typeof(Vector{Vector{T} where T<:Real})` is DataType, and  
`typeof(Vector{Vector{T}} where T<:Real)` is UnionAll.  
Not sure of its implications, but the difference seems significant…

```julia
function f1(u::Vector{Vector{T} where T<:Real})
    u + 1
end

x = Vector{Vector{T} where T<:Real}(2)
x[1] = [1,2]; x[2] = [3,4];
f1(x)

y = Vector{Vector{Int64}}(2)
y[1] = [5,6]; y[2] = [7,8];
f1(y)

function f2(u::Vector{Vector{T}} where T<:Real)
    u + 1
end

f2(y)

```

* * *

Using juliapro 0.6.4.1

```julia
julia> versioninfo()
Julia Version 0.6.4
Commit 9d11f62bcb* (2018-07-09 19:09 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge MAX_THREADS=16)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, sandybridge)

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 5, 2018, 6:07am UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/6 "2018-08-05T06:07:10Z")

</div>

The discussion about [covariance](https://docs.julialang.org/en/latest/manual/types/#Parametric-Composite-Types-1) should help answer your first 2 questions.

If you want to have a method that is dispatched on vectors that contain vectors of real numbers, I would recommend something like

```julia
f(u::AbstractVector{<:AbstractVector{<:Real}}) = ...

```

Note the `AbstractVector`, which makes it works for all ranges, etc.

If you want to create a vector of vectors without automatic conversions, use

```julia
v = Vector{<:Real}[[1], [2.0]]

```

---

<div class="post-metadata">

**Author:** ![suiato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suiato/32/1713_2.png) [@suiato](https://discourse.julialang.org/u/suiato)\
**Post date:** [August 5, 2018, 6:27am UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/7 "2018-08-05T06:27:03Z")

</div>

Thanks 😃 I’ve tried them as follows, and it seems to work well.

I wasn’t aware of the use of AbstractVector, and will have a closer look later.

```julia
f(u::AbstractVector{<:AbstractVector{<:Real}}) = u + 1

```

```
f (generic function with 1 method)

```

```julia
methods(f)

```

1 method for generic function **f** :

- f(u::**AbstractArray{#s1,1} where #s1\<:(AbstractArray{#s2,1} where #s2\<:Real)**) at In[2]:1

```julia
v = Vector{<:Real}[[1], [2.0]]

```

```
2-element Array{Array{#s1,1} where #s1<:Real,1}:
 [1]  
 [2.0]

```

```julia
f(v)

```

```
2-element Array{Array{T,1} where T,1}:
 [2]  
 [3.0]

```

```julia
v1 = Vector{Vector{Real}}(2)
v1[1] = [5]; v1[2] = [6.7];
v1

```

```
2-element Array{Array{Real,1},1}:
 Real[5]  
 Real[6.7]

```

```julia
f(v1)

```

```
2-element Array{Array{T,1} where T,1}:
 [6]  
 [7.7]

```

```julia
v2 = Vector{Vector{Int}}(2)
v2[1] = [8]; v2[2] = [9];
v2

```

```
2-element Array{Array{Int64,1},1}:
 [8]
 [9]

```

```julia
f(v2)

```

```
2-element Array{Array{Int64,1},1}:
 [9] 
 [10]

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 5, 2018, 6:38am UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/8 "2018-08-05T06:38:22Z")

</div>

> [@suiato](#):
>
> `u + 1`

Note that if `u` is a vector of vectors, you will get deprecation warnings about broadcasting later in v0.7. If `+ 1` is your actual use case, see [this topic](https://discourse.julialang.org/t/shorthand-for-1-2-3-4-1/12526).

---

<div class="post-metadata">

**Author:** ![suiato](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suiato/32/1713_2.png) [@suiato](https://discourse.julialang.org/u/suiato)\
**Post date:** [August 5, 2018, 7:32am UTC](https://discourse.julialang.org/t/preferred-type-expression-for-a-vector-of-vectors/12891/10 "2018-08-05T07:32:11Z")

</div>

> [@Tamas\_Papp](#):
>
> > `u + 1`
> 
> Note that if `u` is a vector of vectors, you will get deprecation warnings about broadcasting later in v0.7. If `+ 1` is your actual use case, see [this topic](https://discourse.julialang.org/t/shorthand-for-1-2-3-4-1/12526).

Looked at [the topic](https://discourse.julialang.org/t/shorthand-for-1-2-3-4-1/12526), and made a julia0.7-rc2 version below, using your suggestion in the topic. It worked without error/warnings 🙂

```julia
julia> bc(f) = (args...) -> f.(args...)
bc (generic function with 1 method)

julia> f(u::AbstractVector{<:AbstractVector{<:Real}}) = (bc(+)).(u, 1)
f (generic function with 1 method)

julia> x = Vector{Vector{T} where T<:Real}(undef,2)
2-element Array{Array{T,1} where T<:Real,1}:
 #undef
 #undef

julia> x[1] = [1,2]; x[2] = [3,4];

julia> f(x)
2-element Array{Array{Int64,1},1}:
 [2, 3]
 [4, 5]

julia> y = Vector{Vector{Int64}}(undef,2)
2-element Array{Array{Int64,1},1}:
 #undef
 #undef

julia> y[1] = [5,6]; y[2] = [7,8];

julia> f(y)
2-element Array{Array{Int64,1},1}:
 [6, 7]
 [8, 9]

julia>

```
