# How are vectors of vectors type coerced?

**URL:** https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322
**Category:** General Usage
**Tags:** question
**Created:** [December 6, 2022, 9:28pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322 "2022-12-06T21:28:06Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![jeffreyesun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreyesun/32/13379_2.png) [@jeffreyesun](https://discourse.julialang.org/u/jeffreyesun)
#### Post date: [December 6, 2022, 9:28pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/1 "2022-12-06T21:28:06Z")

</div>

I was having a bug in my code, which basically boils down to this.

```julia
inds = [1,2,3] # Vector{Int}
vals = [1.5, 2.5, 3.5] # Vector{Float64}
ivvec = [inds, vals] # Vector{Vector{Float64}}
ivvec[2][ivvec[1]] #ERROR: ArgumentError: invalid index: 1.0 of type Float64

```

The issue is this:

```julia
inds # Vector{Int}
ivvec[1] # Vector{Float64}

```

Even though `inds` is a `Vector{Int}`, `ivvec[1]` is a `Vector{Float64}`. Once found, this bug is easy to fix. `ivvec = Any[inds, vals]` or `ivvec = (inds, vals)` both do the trick.

Another weird thing is that inds is copied, while vals is just referenced:

```julia
inds[1] = 5 # 5
ivvec[1][1] # 1.0
vals[1] = 5.5 # 5.5
ivvec[2][1] # 5.5

```

Is this the intended behavior? What exactly is happening here?

---

<div class="post-metadata">

### Author: ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)
#### Post date: [December 6, 2022, 9:42pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/2 "2022-12-06T21:42:28Z")

</div>

I don’t have the time to dive into the specific details here, but a general advise: vectors of vectors are rarely a good design pattern in Julia. You have Matrix, N-dimensional Array, StructArrays.jl, Tables.jl and many other data structures that are suitable for efficient lookups with nested buffers.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 6, 2022, 9:42pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/4 "2022-12-06T21:42:57Z")

</div>

> [@jeffreyesun](#):
>
> ```julia
> inds = [1,2,3] # Vector{Int}
> vals = [1.5, 2.5, 3.5] # Vector{Float64}
> ivvec = [inds, vals]
> 
> ```

One solution is to define a `Union`:

```julia
inds = [1,2,3] # Vector{Int}

vals = [1.5, 2.5, 3.5] # Vector{Float64}

ivvec = Union{Vector{Int},Vector{Float64}}[inds, vals]

```

Otherwise, `ivvec` will be promoted to `Vector{Vector{Float64}}`.

---

<div class="post-metadata">

### Author: ![Christopher\_Fisher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christopher_fisher/32/26132_2.png) [@Christopher\_Fisher](https://discourse.julialang.org/u/Christopher_Fisher)
#### Post date: [December 6, 2022, 10:04pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/5 "2022-12-06T22:04:25Z")

</div>

> [@jeffreyesun](#):
>
> Another weird thing is that inds is copied, while vals is just referenced:
> 
> ```julia
> 
> ```

Typically, containers are referenced, but promotion breaks this behavior presumably because the values in the containers are not longer the same. The `Union` type should work as expected.

If your provide more details about your use case, someone might be able to extend juliohm’s advice.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [December 6, 2022, 10:30pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/6 "2022-12-06T22:30:30Z")

</div>

I am really surprised about this. I would have thought for sure it would automatically be a `Vector{Any}`. Breaking of the reference seems particularly odd.

What’s the rationale for doing promotion here? Or rather, what’s the general rule for when promotion happens?

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [December 6, 2022, 10:38pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/7 "2022-12-06T22:38:04Z")

</div>

From [Single- and multi-dimensional Arrays · The Julia Language](https://docs.julialang.org/en/v1/manual/arrays/#man-array-literals)

> If they all have a common [promotion type](https://docs.julialang.org/en/v1/manual/conversion-and-promotion/#conversion-and-promotion) then they get converted to that type using [`convert`](https://docs.julialang.org/en/v1/base/base/#Base.convert) and that type is the array’s `eltype`

A somewhat abstract advice is to use `Vector` for elements which are used for “the same thing”. In your particular example, it would be more tidy to use a `Tuple`:

```julia
ivvec = (inds, vals)

```

---

<div class="post-metadata">

### Author: ![jeffreyesun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreyesun/32/13379_2.png) [@jeffreyesun](https://discourse.julialang.org/u/jeffreyesun)
#### Post date: [December 6, 2022, 11:26pm UTC](https://discourse.julialang.org/t/how-are-vectors-of-vectors-type-coerced/91322/8 "2022-12-06T23:26:50Z")

</div>

Thanks for the info! I see a lot of people trying to “solve my problem,” when there’s a solution right there in the post. I was more just curious about why this happens and whether it’s a bug or a feature.

I guess each step makes sense as a rule,

- automatic promotion in a vector
- promoting a `Vector{Int}` into a `Vector{Float64}`
- copying promoted vectors but referencing non-promoted vectors
- not being able to use a `Float64` as an index

even if taken together they lead to some unintuitive behavior.

I guess if there are Julian lessons here, they are

1. Avoid vectors of vectors
2. Don’t make vectors of different things
