# Getting parent's parametric types parameter

**URL:** <https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470>\
**Category:** General Usage\
**Tags:** parametric-types\
**Created:** [May 22, 2019, 11:28am UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470 "2019-05-22T11:28:49Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cedeerwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cedeerwe/32/8552_2.png) [@cedeerwe](https://discourse.julialang.org/u/cedeerwe)\
**Post date:** [May 22, 2019, 11:28am UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/1 "2019-05-22T11:28:49Z")

</div>

Hey there,

I have some code of this form:

```julia
abstract type AbstractFoo{T}; end

struct SomeFoo <: AbstractFoo{Integer}
  field1::Integer
  field2::Vector{Integer}
end

struct OtherFoo <: AbstractFoo{Float64}
  field1::Float64
  field2::Vector{Float64}
  field3::Dict{Symbol, Float64}
end

```

Is it somehow possible to use the `Integer` & `Float64` from the first line of the type definition in the field types? i.e., something like (obviously not working)?

```julia
struct SomeFoo <: AbstractFoo{T} where T=Integer
  field1::T 
  field2::Vector{T}
end

```

Alternatively, any other way of enforcing all of the fields containing `T` to be equal to `Integer`, by typing it only once?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 22, 2019, 11:42am UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/2 "2019-05-22T11:42:46Z")

</div>

You mean like this?

```julia
struct SomeFoo{T<:Integer} <: AbstractFoo{T}
  field1::T 
  field2::Vector{T}
end

julia> SomeFoo(1, [1, 2])
SomeFoo{Int64}(1, [1, 2])

```

I should also ask why you need the limitation at all? This would stop people using integers or floats with Unitful units, or similar things…

---

<div class="post-metadata">

**Author:** ![cedeerwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cedeerwe/32/8552_2.png) [@cedeerwe](https://discourse.julialang.org/u/cedeerwe)\
**Post date:** [May 22, 2019, 12:33pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/3 "2019-05-22T12:33:14Z")

</div>

> [@Raf](#):
>
> I should also ask why you need the limitation at all? This would stop people using integers or floats with Unitful units, or similar things…

The point is that somewhere in the code, there is a function like this:

```julia
useint(foo::AbstractFoo{Integer}) = factorial(foo.field1)

```

or any other function, which necessarily needs an `Integer` as `field1`. As I have a lot of `Foo`s, I would like to make sure that I do not make some sort of ‘typo’ and create

```julia
struct OneMoreFoo <: AbstractFoo{Integer}
  field1::Float64
end

```

by mistake. Therefore I am looking for a coding pattern, which disallows this.

While your solution does solve the issue, `SomeFoo` is actually a parametric type, while I would like to have it parameter-less.

Maybe the cleanest solution is to create a macro, which does this for me.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 22, 2019, 1:09pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/4 "2019-05-22T13:09:57Z")

</div>

> [@cedeerwe](#):
>
> While your solution does solve the issue, `SomeFoo` is actually a parametric type, while I would like to have it parameter-less

I don’t understand what you mean here. A parametric type can’t be parameter-less?

Also saying “macro” and “cleanest solution” in the same sentence should be a warning sign 😉

---

<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:** [May 22, 2019, 1:34pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/5 "2019-05-22T13:34:11Z")

</div>

> [@cedeerwe](#):
>
> or any other function, which necessarily needs an `Integer` as `field1` . As I have a lot of `Foo` s, I would like to make sure that I do not make some sort of ‘typo’ and create

@Raf’s solution does not conflict with this goal: in fact, it prevents “typos” of this kind, and as for the first problem, you can still restrict with an appropriate method signature, or check the type inside the function with `@assert` or a type assertion `::Integer`.

---

<div class="post-metadata">

**Author:** ![cedeerwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cedeerwe/32/8552_2.png) [@cedeerwe](https://discourse.julialang.org/u/cedeerwe)\
**Post date:** [May 22, 2019, 2:42pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/6 "2019-05-22T14:42:29Z")

</div>

> [@Raf](#):
>
> Also saying “macro” and “cleanest solution” in the same sentence should be a warning sign 😉

I guess you got me on this one 🙂

I have checked some of my code, and found out that the proposed solution fails on a lot of cases of this form

```julia
abstract type AbstractFoo{T}; end

Base.@kwdef struct SomeFoo{T<:Integer} <: AbstractFoo{T}
  field::Vector{T} = Vector{T}()
end

julia> sf = SomeFoo()
ERROR: UndefVarError: T not defined

julia> sf = SomeFoo{Integer}()
SomeFoo{Integer}(Integer[])

```

The point is that the proposed solution only works because it is able to infer the type of `SomeFoo` automatically. If I do

```julia
Base.@kwdef struct OtherFoo <: AbstractFoo{Integer}
  field2::Vector{Integer} = []
end

julia> of = OtherFoo()
OtherFoo(Integer[])

```

everyhing works nicely, but I have the `Integer` there multiple times again.

The solution through the type assertions could work as well, but it would be much nicer if the automatic type assertions checked this for me, without me having to hard-code all of them.

I understand that this is a niché question, so if there is no straightforward solution, I will simply move on with one of the proposed ones and my code will not be much worse. But it would be nice to have 🙂

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 22, 2019, 3:15pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/7 "2019-05-22T15:15:32Z")

</div>

The keyword function is run in a different scope, so It doesn’t “see” the T. You need to use a specific type in the default value, on the right hand side of the =.\

To get around that, define a constructor with default value as a kw arg.

---

<div class="post-metadata">

**Author:** ![cedeerwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cedeerwe/32/8552_2.png) [@cedeerwe](https://discourse.julialang.org/u/cedeerwe)\
**Post date:** [May 22, 2019, 3:23pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/8 "2019-05-22T15:23:05Z")

</div>

> [@Raf](#):
>
> The keyword function is run in a different scope, so It doesn’t “see” the T. You need to use a specific type in the default value, on the right hand side of the =.

True. Do you have any idea how to do this? This approach

```julia
julia> Base.@kwdef struct SomeFoo{T<:Integer} <: AbstractFoo{T}
         field::Vector{T} = []
       end

julia> sf = SomeFoo()
ERROR: MethodError: no method matching SomeFoo(::Array{Any,1})

```

fails and the other possibility of

```julia
julia> Base.@kwdef struct OtherFoo{T<:Integer} <: AbstractFoo{T}
         field::Vector{T} = Integer[]
       end

julia> of = OtherFoo()
OtherFoo{Integer}(Integer[])

```

is again using the `Integer` inside the fields, which did not help.

> [@Raf](#):
>
> To get around that, define a constructor with default value as a kw arg.

Can you give me an example? I feel like this does not solve the duplicite `Integer` issue, rather only pushes the problem to the constructor, but maybe I am wrong.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 22, 2019, 3:40pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/9 "2019-05-22T15:40:37Z")

</div>

You can get `Integer` from `SomeFoo.var.ub` but it’s still going to be a bit of boilerplate. And you can put that in the kwdef too. I was imagining you could do it for AbstractFoo but its not so easy.

Time for that macro 🙂

---

<div class="post-metadata">

**Author:** ![cedeerwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cedeerwe/32/8552_2.png) [@cedeerwe](https://discourse.julialang.org/u/cedeerwe)\
**Post date:** [May 22, 2019, 3:44pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/10 "2019-05-22T15:44:35Z")

</div>

Yep, it seems so 🙂

Thanks for the effort anyway, already learned a lot!

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 22, 2019, 3:45pm UTC](https://discourse.julialang.org/t/getting-parents-parametric-types-parameter/24470/11 "2019-05-22T15:45:35Z")

</div>

Or probaly just live with the boilerplate for a while
