# How to call constructor of parametric family of types efficiently

**URL:** https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503
**Category:** Performance
**Created:** [April 30, 2020, 7:20pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503 "2020-04-30T19:20:06Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)
#### Post date: [April 30, 2020, 7:20pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/1 "2020-04-30T19:20:06Z")

</div>

I would like to call the constructor of several parametric families of types efficiently, while only having access to a concrete instance of a type. Also, I am trying to avoid having to write a separate method for each family.

For instance, given `x::A{T}`, I would like to call the constructor `A`, and not `A{T}`.

I came up with the following,

```julia
constructor = eval(Meta.parse(string(typeof(x).name)))

```

but is there a more efficient and/or elegant solution to this problem?

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [April 30, 2020, 8:04pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/3 "2020-04-30T20:04:30Z")

</div>

If they share a common supertype:

```julia
julia> abstract type B end

julia> struct A{T} <: B
          field
       end

julia> struct C <: B end

julia> A() = A{String}("hello")
A

julia> A{Int}(1) |> typeof |> supertype |> subtypes |> y -> filter(x -> x <: A, y)[1]()
A{String}("hello")

```

That is

```julia
function constructor(x::F) where F
   types = subtypes(supertype(F))
   return types[findfirst(x -> F <: x, types)]
end

```

But I do have to say, this doesn’t feel right to do. What’s your usecase beyond wanting to do this to save some methods? This strangely enough feels like a factory pattern and I can’t quite imagine how you’d end up with that architecture using julia in the first place.

---

<div class="post-metadata">

### Author: ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)
#### Post date: [April 30, 2020, 8:25pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/4 "2020-04-30T20:25:11Z")

</div>

I am working on a module with a number of parametric types. Instances of these types can further be combined in arbitrary ways using an algebra that is defined on them. All types have a parametric type which corresponds to the type of the number field on which they are defined. This is similar to the first type parameter in Julia’s arrays.

Given such a composite type with an associated field type, I need to construct instances with the same hierarchical structure (based on the algebra) but a different field type.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [April 30, 2020, 8:26pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/5 "2020-04-30T20:26:35Z")

</div>

This is a relatively hard problem, see e.g. the discussion on [Stripping parameter from parametric types](https://discourse.julialang.org/t/stripping-parameter-from-parametric-types/8293) here on discourse, or the paragraph on [Design Patterns with Parametric Methods](https://docs.julialang.org/en/latest/manual/methods/#Building-a-similar-type-with-a-different-type-parameter-1) in the documentation.

  

> [@SEA](#):
>
> I am trying to avoid having to write a separate method for each family.

I would think that building a separate method for each family remains the most idiomatic solution. This is more or less what [similar](https://docs.julialang.org/en/latest/base/arrays/#Base.similar) does, for example.

  

* * *
  

That being said, if you really want a fully generic implementation, something like this might work:

```julia
stripped_type(x) = stripped_type(typeof(x))
stripped_type(typ::DataType) = Base.typename(typ).wrapper

```

For example:

```julia
julia> struct A{T}
           x::T
       end

julia> a = A(42)
A{Int64}(42)

julia> stripped_type(a)(42.5)
A{Float64}(42.5)

```

Again, I would not recommend such a solution, which relies too much on internal details to my taste.

---

<div class="post-metadata">

### Author: ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)
#### Post date: [April 30, 2020, 8:33pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/6 "2020-04-30T20:33:49Z")

</div>

Thank you for the references!

> [@ffevotte](#):
>
> This is more or less what [similar](https://docs.julialang.org/en/latest/base/arrays/#Base.similar) does, for example.

As a matter of fact, I am extending similar 🙂

I am tending towards using meta-programming for each family then. There are too many types to write this by hand. Depending on ones taste, that might still rely on a lot of internals. It will probably be the most performant solution though.

---

<div class="post-metadata">

### Author: ![SEA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sea/32/8956_2.png) [@SEA](https://discourse.julialang.org/u/SEA)
#### Post date: [April 30, 2020, 8:37pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/7 "2020-04-30T20:37:49Z")

</div>

I am not able to accept an answer for some reason. But thank you for your input.

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [April 30, 2020, 8:38pm UTC](https://discourse.julialang.org/t/how-to-call-constructor-of-parametric-family-of-types-efficiently/38503/8 "2020-04-30T20:38:23Z")

</div>

FYI [https://github.com/JuliaObjects/ConstructionBase.jl](https://github.com/JuliaObjects/ConstructionBase.jl) is designed to solve this problem. You can use `constructorof` as-is if you are not doing anything fancy in the constructor.
