# How to build data structures on Arrays without specifying the array implementation?

**URL:** <https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251>\
**Category:** General Usage\
**Tags:** arrays\
**Created:** [March 16, 2021, 12:38am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251 "2021-03-16T00:38:57Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![marty0801](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marty0801/32/12715_2.png) [@marty0801](https://discourse.julialang.org/u/marty0801)\
**Post date:** [March 16, 2021, 12:38am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/1 "2021-03-16T00:38:57Z")

</div>

I’ve built some data structures on `Vector`s, and now realize I should be using views instead. The problem is that I need indexing operations to return another container. How do I modify my struct definitions to achieve this? Example:

```julia
struct Container{T} 
   box::Vector{T} 
   ...
end 
# other code requires that container[idx] returns another container: 
Base.getindex(c::Container{T}, idx) where {T}= Container{T}(c.box[idx]) 

```

My first thought (after google searching failed) was to attempt to abstract over the vector type:

```julia
struct Container{A,T} 
    box::A{T} 
end 

```

thinking I could recover the original struct with `c=Container{Vector,T}`, but this gives an error I don’t understand:

```julia
ERROR: TypeError: in Type{...} expression, expected UnionAll, got a value of type TypeVar

```

I suppose the larger question is: How does one write datatypes with generic arrays? Thanks!

---

<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:** [March 16, 2021, 12:43am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/2 "2021-03-16T00:43:22Z")

</div>

If it supports `getindex`, possibly `struct Container{T}` should be a subtype of `AbstractVector`? Then the caller can use `@views` to do slicing with views and it will create a `SubArray{Container}`.

Alternatively, you can declare it as:

```julia
struct Container{T<:AbstractVector} 
   box::T
   ...
end 

```

and then you can just store a view (`SubArray`) if you want:

```julia
Base.getindex(c::Container, idx) = Container(@view c.box[idx]) 

```

---

<div class="post-metadata">

**Author:** ![marty0801](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marty0801/32/12715_2.png) [@marty0801](https://discourse.julialang.org/u/marty0801)\
**Post date:** [March 16, 2021, 1:12am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/3 "2021-03-16T01:12:33Z")

</div>

But this seems to hide the element type. Is there a way to do as you suggest, but still have access to the element type of the Vector?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [March 16, 2021, 1:34am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/4 "2021-03-16T01:34:28Z")

</div>

It seems that you just want to use AbstractVector instead of vector:

```julia
struct Foo{T}
  v:: AbstractVector{T}
end

v = [1,2,3]
x = Foo(v)
y = Foo(@view v[2:3])

```

Edit: just for the records, this is not a good idea because fields with abstract types lead to performance losses, as pointed below (and above, implicitly). Honestly I made a confusion at that moment in which I imagined (wrongly) that the instance of the struct would assume the specific type of the value used in the generator (as functions specialize for them). Of course it does not.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 16, 2021, 2:33am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/5 "2021-03-16T02:33:18Z")

</div>

Having an abstract field type like that will significantly harm performance. Instead, you can do:

```julia
struct Foo{T, V <: AbstractVector{T}}
  v::V 
end

```

if you want the element type `T` to be an explicit type parameter.

Also note that this isn’t strictly necessary. You can use @stevengj’s suggestion and implement `Base.eltype` for your `Container` with no loss of performance or expressiveness.

---

<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:** [March 16, 2021, 2:38am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/6 "2021-03-16T02:38:15Z")

</div>

> [@marty0801](#):
>
> But this seems to hide the element type. Is there a way to do as you suggest, but still have access to the element type of the Vector?

`Base.eltype(c::Container) = eltype(c.box)` works and is fast (it will evaluate to a compile-time constant).

---

<div class="post-metadata">

**Author:** ![marty0801](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marty0801/32/12715_2.png) [@marty0801](https://discourse.julialang.org/u/marty0801)\
**Post date:** [March 16, 2021, 10:58am UTC](https://discourse.julialang.org/t/how-to-build-data-structures-on-arrays-without-specifying-the-array-implementation/57251/7 "2021-03-16T10:58:37Z")

</div>

Thanks; exactly what I was looking for! And placing the new type parameter at the tail of the Foo{…} signature, as you showed, obviated any changes to the calling code. This made it trivial to use views instead of Vectors, my ultimate goal.
