# Composite type whose fields are all different suptypes of a supertype

**URL:** <https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689>\
**Category:** New to Julia\
**Tags:** type, parametric-types\
**Created:** [November 4, 2019, 11:18am UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689 "2019-11-04T11:18:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [November 4, 2019, 11:18am UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/1 "2019-11-04T11:18:45Z")

</div>

I have a composite type whose fields are all different suptypes of a supertype. Can this be expresses in a more elagnat way then shown below?

```julia
struct Operators{A<:AbstractArray{Float64,2}, L<:AbstractArray{Float64,2}, D<:AbstractArray{Float64,2}, AH<:AbstractArray{Float64,2}, LH<:AbstractArray{Float64,2}, DH<:AbstractArray{Float64,2},AE<:AbstractArray{Float64,2}, LE<:AbstractArray{Float64,2}, DE<:AbstractArray{Float64,2}}
    𝕴::A
    𝕴ₑ::AE
    𝕴ₕ::AH
    𝔏::L
    𝔏ₑ::LE
    𝔏ₕ::LH
    𝔇::D
    𝔇ₑ::DE
    𝔇ₕ::DH
end
end

```

I thout about someting like

```julia
struct Operators{A, L, D, AH, LH, DH, L, LE, DE} where {A, L, D, AH, LH, DH, L, LE, DE} <:AbstractArray{Float64,2}
    𝕴::A
    𝕴ₑ::AE
    𝕴ₕ::AH
    𝔏::L
    𝔏ₑ::LE
    𝔏ₕ::LH
    𝔇::D
    𝔇ₑ::DE
    𝔇ₕ::DH
end

```

Any suggestions about style and how to do better are welcome.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [November 4, 2019, 11:53am UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/2 "2019-11-04T11:53:22Z")

</div>

You can enforce this on construction, but sadly it seems you can’t write `new{typeof.(args)...}(args...)` here:

```julia
julia> struct Operators2{A, L, D}
       𝕴::A
       𝔏::L
       𝔇::D
       Operators2(args::AbstractArray{Float64}...) = new{typeof(args[1]), typeof(args[2]), typeof(args[3])}(args...)
       end

julia> Operators2(rand(2,2), rand(2,2)', rand(2,3))
Operators2{Array{Float64,2},LinearAlgebra.Adjoint{Float64,Array{Float64,2}},Array{Float64,2}}([...
...])

```

Edit: you can do that if it isn’t attached to `new`, like so:

```julia
julia> struct Operators3{A, L, D}
       𝕴::A
       𝔏::L
       𝔇::D
       end

julia> Operators3(args::AbstractArray{Float64}...) = Operators3{typeof.(args)...}(args...);
julia> Operators3(args...) = error("nope");
julia> Operators3(A,L,D) = error("nope");

julia> Operators3(rand(2,2), rand(2,2), rand(2))
ERROR: nope

julia> Operators3(rand(2,2), rand(2,2))
ERROR: MethodError:

```

---

<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:** [November 4, 2019, 12:19pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/3 "2019-11-04T12:19:45Z")

</div>

Just don’t enforce types 🙂

---

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [November 4, 2019, 12:20pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/4 "2019-11-04T12:20:13Z")

</div>

exactly what I was looking for

```julia
Operators3(args::AbstractArray{Float64}...) = Operators3{typeof.(args)...}(args...);

```

thx

---

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [November 4, 2019, 12:23pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/5 "2019-11-04T12:23:56Z")

</div>

> [@Raf](#):
>
> Just don’t enforce types

Is there a specific reason why not? (what would the compiler say about that, would it make any difference in terms of performance…)

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [November 4, 2019, 12:35pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/6 "2019-11-04T12:35:19Z")

</div>

If I understand right it should make no difference to the compiler, 99% of the time.

Strongly enforcing types (like `Float64`) generally seems like a bad idea, as it means I won’t be able to use say ForwardDiff through your code, or some other exotic numbers.

But weakly enforcing that things are `AbstractMatrix`es etc. often seems like a good idea, so that when you give it obviously wrong arguments (e.g. because you forgot to splat a tuple somewhere) you get an error early on, not 15 steps into your calculation.

---

<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:** [November 4, 2019, 12:39pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/7 "2019-11-04T12:39:33Z")

</div>

> [@MatFi](#):
>
> what would the compiler say about that, would it make any difference in terms of performance…

The compiler will not care as long types are _concrete_. Just

[https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type-1](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type-1)

and you will be fine.

---

<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:** [November 4, 2019, 12:49pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/8 "2019-11-04T12:49:30Z")

</div>

Basically it makes no performance difference as long as you use parametric types on your structs, as described in the performance tips.

Types are best used for method dispatch and occasionally to find/prevent bugs. But performance will be the same without them, and they are actually limiting the flexibility of your code.

---

<div class="post-metadata">

**Author:** ![MatFi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matfi/32/10002_2.png) [@MatFi](https://discourse.julialang.org/u/MatFi)\
**Post date:** [November 4, 2019, 1:07pm UTC](https://discourse.julialang.org/t/composite-type-whose-fields-are-all-different-suptypes-of-a-supertype/30689/9 "2019-11-04T13:07:00Z")

</div>

Ok thanks to all for teaching me this lesson. I should have read the performance tips in detail earlier. There one can find the nice sentence

> Once one learns to appreciate multiple dispatch, there’s an understandable tendency to go overboard and try to use it for everything.

which describes exactly the situation I’m in.  
So I just stay concrete with mild type enforcement…
