# How should I declare “abstract container type” fields in v0.6?

**URL:** <https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325>\
**Category:** General Usage\
**Created:** [February 26, 2017, 11:27pm UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325 "2017-02-26T23:27:08Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)\
**Post date:** [February 26, 2017, 11:27pm UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/1 "2017-02-26T23:27:08Z")

</div>

Hi,

Is there an updated information for how to create an abstract container type in v0.6?

Here’s the corresponding info for 0.4:

[How should I declare “abstract container type” fields?](http://web.mit.edu/julia_v0.4.3/.julia-a2f713dea5.amd64_ubuntu1404/share/doc/julia/html/manual/faq.html#how-should-i-declare-abstract-container-type-fields)

Is it now recommended to inherit from AbstractArray?

Thanks,

Glen

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 27, 2017, 8:01am UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/2 "2017-02-27T08:01:02Z")

</div>

That advice still holds: type-fields used in performance critical parts of a code should have a concrete type. If you want the type-field to hold a range of types you need to parameterize the type.

You can check that yourself (using the linked example):

```julia
               _
   _ _ _(_)_ | A fresh approach to technical computing
  (_) | (_) (_) | Documentation: http://docs.julialang.org
   _ _ _| |_ __ _ | Type "?help" for help.
  | | | | | | |/ _` | |
  | | |_| | | | (_| | | Version 0.6.0-dev.2826 (2017-02-14 13:01 UTC)
 _/ |\ __'_|_|_|\__'_| | Commit 2ecc2157c5* (12 days old master)
|__/ | x86_64-pc-linux-gnu

julia> type MySimpleContainer{A<:AbstractVector}
            a::A
       end

julia> type MyAmbiguousContainer{T}
            a::AbstractVector{T}
       end

julia> f(v) = v.a
f (generic function with 1 method)

julia> @code_warntype f(MySimpleContainer([1]))
Variables:
  #self#::#f
  v::MySimpleContainer{Array{Int64,1}}

Body:
  begin
      return (Core.getfield)(v::MySimpleContainer{Array{Int64,1}}, :a)::Array{Int64,1}
  end::Array{Int64,1} # good

julia> @code_warntype f(MyAmbiguousContainer([1]))
Variables:
  #self#::#f
  v::MyAmbiguousContainer{Int64}

Body:
  begin
      return (Core.getfield)(v::MyAmbiguousContainer{Int64}, :a)::AbstractArray{Int64,1}
  end::AbstractArray{Int64,1} # bad

```

---

<div class="post-metadata">

**Author:** ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)\
**Post date:** [February 27, 2017, 3:02pm UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/3 "2017-02-27T15:02:22Z")

</div>

That is a very helpful example, thanks. Would you not inherit from AbstractArray to get a bunch of functionality? I thought that was improved in v0.6.

Is there a good way to restrict the element type of v.a to be a subtype of Number and be performant? Similarly, if I try to restrict the eltype with a function call I run into problems:

```julia
julia> g{A<:AbstractVector,N<:Number}(m::MySimpleContainer{A{N}}) = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar

julia> g(m::MySimpleContainer{A{N}}) where N<:Number where A<:AbstractVector = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar

julia> g{A<:AbstractVector}(m::MySimpleContainer{A{<:Number}}) = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got TypeVar

julia> g{A<:AbstractVector}(m::MySimpleContainer{A}) where N<:Number where A <: AbstractVector{N}= "yes"
ERROR: UndefVarError: N not defined

julia> g{A<:AbstractVector}(m::MySimpleContainer{A}) where A<:AbstractVector{N} where N<:Number = "yes"
ERROR: TypeError: Type{...} expression: expected UnionAll, got #g

```

After reading the manual, I’m not sure how to use the `where` clause effectively.

Glen

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 27, 2017, 4:11pm UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/4 "2017-02-27T16:11:10Z")

</div>

> [@Glen](#):
>
> That is a very helpful example, thanks. Would you not inherit from AbstractArray to get a bunch of functionality? I thought that was improved in v0.6.

Yes, but that is in 0.5 already (but maybe it improved). (But that is a different topic to the section of the manual you link to). See [http://docs.julialang.org/en/stable/manual/interfaces/](http://docs.julialang.org/en/stable/manual/interfaces/) for the bits you need to implement additionally.

> [@Glen](#):
>
> Is there a good way to restrict the element type of v.a to be a subtype of Number and be performant?

```julia
type MySimpleContainer{A<:Number}
            a::A
       end

```

> [@Glen](#):
>
> After reading the manual, I’m not sure how to use the where clause effectively.

I struggle too 🙂 . This seems ok:

```julia
g(m::MySimpleContainer{A}) where A<:AbstractVector{N} where N<:Number = "yes"

```

---

<div class="post-metadata">

**Author:** ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)\
**Post date:** [February 28, 2017, 1:51am UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/5 "2017-02-28T01:51:11Z")

</div>

The type definition and inheritance make things more complicated. I’d like to define a type that has the same constraints as:

```julia
g(m::MySimpleContainer{A}) where A<:AbstractVector{N} where N<:Number = "yes"

```

I’d like to define a container type that inherits from AbstractVector and is limited to Numbers. Like:

```julia
struct MySimpleContainer{A} where A<:AbstractVector{N} where N<:Number <: AbstractVector{N}
    data::A
end

```

But `where` clauses are not allowed in type definitions so I’m not sure what is the best way to do this.

Thanks,

Glen

---

<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:** [February 28, 2017, 2:03am UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/6 "2017-02-28T02:03:42Z")

</div>

You mean

```julia
julia> struct MySimpleContainer{N<:Number,A<:AbstractVector{N}} <: AbstractVector{N}
       end

```

?

---

<div class="post-metadata">

**Author:** ![Glen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/glen/32/3583_2.png) [@Glen](https://discourse.julialang.org/u/Glen)\
**Post date:** [February 28, 2017, 2:59am UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/7 "2017-02-28T02:59:59Z")

</div>

Hi yuyichao,

Thanks for the help. This is pretty exciting as it now works and should be performant:

```julia
julia> struct MySimpleContainer{N<:Number,A<:AbstractVector{N}} <: AbstractVector{N}
         data::A
       end

julia> Base.size(m::MySimpleContainer) = size(m.data)

julia> Base.getindex(m::MySimpleContainer, idx) = getindex(m.data, idx)

julia> MySimpleContainer(data::AbstractVector) = MySimpleContainer{eltype(data),typeof(data)}(data)
MySimpleContainer

julia> MySimpleContainer([1,2,3])
3-element MySimpleContainer{Int64,Array{Int64,1}}:
 1
 2
 3

julia> f(x) = x.data
f (generic function with 1 method)

julia> @code_warntype f(MySimpleContainer([1,2,3]))
Variables:
  #self#::#f
  x::MySimpleContainer{Int64,Array{Int64,1}}

Body:
  begin
      return (Core.getfield)(x::MySimpleContainer{Int64,Array{Int64,1}}, :data)::Array{Int64,1}
  end::Array{Int64,1}

julia> typeof(MySimpleContainer([1,2,3]))
MySimpleContainer{Int64,Array{Int64,1}}

```

I wasn’t sure the best way to do the outer constructor but it seems to work.

Is there any way to get a type of the container to be `MySimpleContainer{Array{Int64,1}}` so `Int64` isn’t there twice (it seems kind of redundant).

Glen

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 28, 2017, 8:46am UTC](https://discourse.julialang.org/t/how-should-i-declare-abstract-container-type-fields-in-v0-6/2325/8 "2017-02-28T08:46:46Z")

</div>

> [@Glen](#):
>
> Is there any way to get a type of the container to be MySimpleContainer{Array{Int64,1}} so Int64 isn’t there twice (it seems kind of redundant).

No, that is not possible. Related issue: [Proposal: Defer calculation of field types until type parameters are known · Issue #18466 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/18466)
