# Why does a = Vector{\<:Real}(undef, 2) fail?

**URL:** <https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 6, 2018, 3:28am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359 "2018-12-06T03:28:20Z")\
**Posts on this page:** 12\
**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:** [December 6, 2018, 3:28am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/1 "2018-12-06T03:28:20Z")

</div>

Why does `a = Vector{<:Real}(undef, 2) ` fail, giving the following error?  
`MethodError: no method matching Array{#s1,1} where #s1&lt;:Real(::UndefInitializer, ::Int64)`

(Julia version 1.0)

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 6, 2018, 3:36am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/2 "2018-12-06T03:36:53Z")

</div>

`Vector{<:Real}` (short of `Vector{T} where T<:Real`) is not a concrete type and in this case it’s unclear what exactly you want to construct so there isn’t a method defined for this to guess what you want.

---

<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:** [December 6, 2018, 4:06am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/3 "2018-12-06T04:06:19Z")

</div>

But, `c = Vector{Real}(undef, 2)` works, while Real isn’t a concrete type.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 6, 2018, 4:12am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/4 "2018-12-06T04:12:25Z")

</div>

That’s exactly why I spelled out the type for you. `Real` isn’t a concrete type but `Vector{Real}` is. `Vector{T} where T<:Real` isn’t a concrete type because it’s a class (`UnionAll`) of types constraint by the `where`

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [December 6, 2018, 4:12am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/5 "2018-12-06T04:12:38Z")

</div>

`Vector{Real}` is a concrete type, a vector holding any `Real`.

What would be the element type of `Vector{<:Real}` ? You haven’t specified `T`.

---

<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:** [December 6, 2018, 4:24am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/6 "2018-12-06T04:24:41Z")

</div>

Thank you for the comment. I wasn’t aware `a = Vector{T} where T<:Real` was of UnionAll. When I checked `d = Vector{T} where T<:Real; typeof(d)` , it’s UnionAll, indeed 🙂

---

<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:** [December 6, 2018, 4:38am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/7 "2018-12-06T04:38:25Z")

</div>

Actually, I was creating a vector of vectors `vv = Vector{Vector{<:Real}}(undef, 2)`, which worked. So, I assumed `vv[1] = Vector{<:Real}(undef, 2)` would work. Well, it seems I was wrong.

In practice, I’ll do `vv[1] = Vector{Real}(undef, 2)` and will have no problem.

Now, it’s still unclear to me why vv above works… when I checked the type of vv above, it’s DataType.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [December 6, 2018, 5:02am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/8 "2018-12-06T05:02:16Z")

</div>

> [@suiato](#):
>
> Now, it’s still unclear to me why vv above works… when I checked the type of vv above, it’s DataType.

And that’s exactly why I always hated the `<:` notation… `Vector{Vector{<:Real}}` is `Vector{Vector{T} where T<:Real}`, i.e. a `Vector` of the abstract type `Vector{T} where T<:Real`. It is not `Vector{Vector{T}} where T<:Real` which would be an abstract type (`UnionAll`). `<:T` isn’t a value (there’s no value `X` where `Vector{X}` is `Vector{<:Real}`) rather a syntax that moves out of the enclosing`{}`. However, it only move **one** level of `{}` making it really confusing for beginners (and expers when not paying attention).

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [December 6, 2018, 5:31am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/9 "2018-12-06T05:31:55Z")

</div>

Yes I can see why this seems confusing.

One way to look at it is you can create a concrete `Vector` with an abstract element type as long as that element type is well specified.  
However you can’t create a Vector with “unspecified” element type.

Perhaps related, compare:

```julia
Vector{Vector{Real}} # concrete
Vector{Vector{T} where T<:Real} # concrete
Vector{Vector{T}} where T<:Real # abstract, T not specified

```

---

<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:** [December 6, 2018, 3:50pm UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/10 "2018-12-06T15:50:52Z")

</div>

Thank you for the comments. Now I understand the subtle syntax issue much better.

---

<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:** [January 19, 2019, 12:13am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/11 "2019-01-19T00:13:40Z")

</div>

As mentioned above, use of \<: such as Vector{Matrix{\<:Real}} is a bit confusing…

```julia
a = [[1 2 3;4 5 6],[3 2 1;6 5 4]]

function temp(a::Vector{Matrix{<:Real}})
    a
end
temp(a)

```

```
MethodError: no method matching temp(::Array{Array{Int64,2},1})
Closest candidates are:
  temp(::Array{Array{#s1,2} where #s1<:Real,1}) at In[1]:4

```

```julia
It's the same as

```

```julia
function temp1(a::Vector{Matrix{T} where T<:Real})
    a
end
temp(a)

```

```
MethodError: no method matching temp(::Array{Array{Int64,2},1})
Closest candidates are:
  temp(::Array{Array{#s1,2} where #s1<:Real,1}) at In[1]:4

```

However, this works:

```julia
function temp2(a::Vector{<:Matrix{<:Real}})
    a
end
temp2(a)

```

```
2-element Array{Array{Int64,2},1}:
 [1 2 3; 4 5 6]
 [3 2 1; 6 5 4]

```

I sort of understand why, but will appreciate a good explanation.

As suggested in one of the comments above in this thread, maybe better avoid such use of \<: if I don’t understand it very well? The following function works well and easier to understand.

```julia
function temp3(a::Vector{Matrix{T}} where T<:Real)
    a
end
temp3(a)

```

```
2-element Array{Array{Int64,2},1}:
 [1 2 3; 4 5 6]
 [3 2 1; 6 5 4]

```

---

<div class="post-metadata">

**Author:** ![Azamat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azamat/32/6892_2.png) [@Azamat](https://discourse.julialang.org/u/Azamat)\
**Post date:** [January 19, 2019, 3:52am UTC](https://discourse.julialang.org/t/why-does-a-vector-real-undef-2-fail/18359/12 "2019-01-19T03:52:17Z")

</div>

Because parametric types in Julia are invariant. From [documentation](https://docs.julialang.org/en/latest/manual/types/#Parametric-Composite-Types-1):

> This last point is _very_ important: even though `Float64 <: Real` we **DO NOT** have `Point{Float64} <: Point{Real}`.

So translating this to your case:

- `Vector{Matrix{Int}} <: Vector{Matrix{<:Real}}` is **false**.
- `Vector{Matrix{Int}} <: Vector{<:Matrix{Real}}` is **false**.

But if you want covariance then

- `Vector{Matrix{Int}} <: Vector{<:Matrix{Int}}` is **true**
- `Vector{Matrix{Int}} <: Vector{<:Matrix{<:Real}}` is **true**
- `Vector{Matrix{Int}} <: Vector{Matrix{T}} where T<:Real` is **true**
- etc.
