# Cannot define parametric type with parametric field

**URL:** <https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016>\
**Category:** General Usage\
**Tags:** question, parametric-types\
**Created:** [March 19, 2019, 3:24am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016 "2019-03-19T03:24:52Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)\
**Post date:** [March 19, 2019, 3:24am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/1 "2019-03-19T03:24:52Z")

</div>

I am trying to define a type that support multiple array backends but the compiler complains:

```julia
struct A{R} # TypeError: in Type{...} expression, expected UnionAll, got TypeVar
    mat::R{Int,2}
    vec::R{Int,1}
end

```

In my mind `R` can be one of `Array`, `BitArray`, `CuArray`, `SharedArray`, etc.

One alternatives I can think of

```julia
struct A{Tmat<:AbstractArray{Int,2}, Tvec<:AbstractArray{Int,1}}
    mat::Tmat
    vec::Tvec
end

```

But it is much more verbose & hooked up to `AbstractArray` & lost the constraint that `mat` and `vec` share the same backend.

I am wondering how do people cope with this. Thoughts?

---

<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:** [March 19, 2019, 8:12am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/2 "2019-03-19T08:12:38Z")

</div>

> [@cnliao](#):
>
> I am wondering how do people cope with this.

Using eg the solution you did above. AFAIK you cannot parametrize type _names_, only type _parameters_, which makes sense if you think about it.

If you definitely want to enforce that eg both `mat` and `vec` are `Array`, use an inner constructor. But IMO it should not be necessary in most cases I can think of, there is no reason not to keep your code fully generic. Recently I got into the habit of even leaving out the supertypes, and just relying on duck typing (“if it breaks, you will know”).

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 19, 2019, 9:09am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/3 "2019-03-19T09:09:52Z")

</div>

For a lot more discussion on this kind of thing, see [https://github.com/JuliaLang/julia/issues/18466](https://github.com/JuliaLang/julia/issues/18466)

---

<div class="post-metadata">

**Author:** ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)\
**Post date:** [March 19, 2019, 10:41am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/4 "2019-03-19T10:41:09Z")

</div>

Yes. But since I am sure my code will break some day, I would like to be able to use precautions here and there, rather than going full generic.

---

<div class="post-metadata">

**Author:** ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)\
**Post date:** [March 19, 2019, 10:41am UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/5 "2019-03-19T10:41:59Z")

</div>

Exactly the discussion I am expecting to see! Thank you very much!

---

<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:** [March 19, 2019, 2:06pm UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/6 "2019-03-19T14:06:13Z")

</div>

IMO the protection from overspecifying types is partly an illusion (even though I also use it). It just makes your code somewhat brittle, as subtyping does not allow something to conform to two disjoint interfaces — eg something can be an `<: AbstractArray` **and** something else at the same time.

Also, duck typing (allowing things to fail because methods are undefined) will lead to an error anyway.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 19, 2019, 2:30pm UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/7 "2019-03-19T14:30:05Z")

</div>

Just to make this a bit more concrete — you can’t do this because type parameters don’t have a generic meaning. The first type parameter is not always the element type. The second type parameter is not always the dimensionality. A great example is `BitArray`: it only has one parameter and thus could not be meaningfully substituted in for `R` in your example. Conversely matrices like `SparseMatrixCSC` and `Diagonal` don’t have a dimensionality parameter since they are by definition 2-dimensional.

The way to enforce a constraint like this is just through the constructor.

---

<div class="post-metadata">

**Author:** ![cnliao](https://avatars.discourse-cdn.com/v4/letter/c/ce73a5/32.png) [@cnliao](https://discourse.julialang.org/u/cnliao)\
**Post date:** [March 19, 2019, 2:49pm UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/8 "2019-03-19T14:49:35Z")

</div>

Yes I agree about the “illusion ” part. Nonetheless I sometimes still want to have something like “enforcement of encapsulation” or “gerrenteed correctness/throw ”. The Julia language itself enforced so little that I often feel a lack of discipline. I am looking in established projects for ideas but has yet to distill enough essences to form some doctrines like one would find in any book about c++ design patterns.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 19, 2019, 2:59pm UTC](https://discourse.julialang.org/t/cannot-define-parametric-type-with-parametric-field/22016/9 "2019-03-19T14:59:21Z")

</div>

You can enforce this constraint. It’s just done with the constructor instead of the struct layout.
