# Structure inheritance

**URL:** <https://discourse.julialang.org/t/structure-inheritance/118699>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 28, 2024, 10:30am UTC](https://discourse.julialang.org/t/structure-inheritance/118699 "2024-08-28T10:30:17Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mesonepigreco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mesonepigreco/32/46262_2.png) [@mesonepigreco](https://discourse.julialang.org/u/mesonepigreco)\
**Post date:** [August 28, 2024, 10:30am UTC](https://discourse.julialang.org/t/structure-inheritance/118699/1 "2024-08-28T10:30:17Z")

</div>

Hi, I have defined an abstract type AbstractQuantumParticle, and then a specific structure QuantumParticle \<: AbstractQuantumParticle  
which has some fields like position and momentum.  
Let us say now I want to add an extra particle Fermion \<: AbstractQuantumParticle, which also has a spin variable, but that also works with all the methods that interface with QuantumParticle via the multiple dispatch (plus some specific dispatching for it).

The easiest solution is to copy all the content of QuantumParticle inside Fermion, and add the spin. However, in this way if I have to add something to QuantumParticle in the future, this needs to be done also to the Fermion structure.

Is there a more elegant way (via a decorator, for example) to tell the Fermion structure to track and copy all the attributes of the QuantumParticle structure?

This is similar to OOP inheritance but much simpler (I do not want to go OOP, no class, just a simple structure). I saw many packages to bring the OOP paradigm in Julia, but that is not what I want; a simple tracker that acts like a precompile directive would be much better.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 28, 2024, 11:01am UTC](https://discourse.julialang.org/t/structure-inheritance/118699/2 "2024-08-28T11:01:49Z")

</div>

There isn’t a straightforward way to do this because it’s exactly what inheritance is, and concrete subtyping does not work well with multiple dispatch. This is a reasonable want, though, and something similar is done.

Perhaps you’ve heard of the composite reuse principle of OOP, or “composition over inheritance.” Julia does it much more by necessity. If you want all `QuantumParticle` methods to work on `Fermion`, the easiest way is to have `Fermion` contain `QuantumParticle`, then you just forward `foo(fermion.quantumparticle)`. You could dispatch a getter like `getquantumparticle` over different types so you aren’t writing and branching to various dot notation sequences everywhere. That getter can be incorporated into a `foo` method as well for a short `foo(fermion)`. (I’m assuming this is a toy example, not an actual use case where you would likely prefer to have actual fermions as concrete subtypes of an abstract `Fermion`). Refactoring overuse of inheritance and dot notation is a very OOP practice, so this isn’t even a culture shock.

Different packages like MacroTools.jl and Lazy.jl have made forwarding macros to pull off something closer to how concrete inheritance feels, but I’m not aware of a standard package maintained for this purpose. Strictly speaking, forwarding is not ever inheritance because inherited methods work directly on an instance of the subclass, not the superclass.

---

<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:** [August 28, 2024, 11:38am UTC](https://discourse.julialang.org/t/structure-inheritance/118699/3 "2024-08-28T11:38:01Z")

</div>

> [@mesonepigreco](#):
>
> Fermion \<: AbstractQuantumParticle, which also has a spin variable, but that also works with all the methods that interface with QuantumParticle via the multiple dispatch (plus some specific dispatching for it)

Sure, you can do this, but the exact implementation depends on _what the API is for `QuantumParticle`._

Eg if you expose `get_position` and `get_momentum`, you can just implement these methods to forward the value from the relevant field for `Fermion`. If you want the `Base.getproperty` to work (`.position`), you need a different approach, but it is doable.

Please provide specific and then you may get a more detailed answer.

(Also, please [quote your code](https://discourse.julialang.org/t/psa-how-to-quote-code-with-backticks/7530).)

---

<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:** [August 28, 2024, 11:53am UTC](https://discourse.julialang.org/t/structure-inheritance/118699/4 "2024-08-28T11:53:28Z")

</div>

You really don’t want field inheritance. I wrote Mixers.jl to do this years ago and never use it. Most similar packages are also not widely used. While field inheritance at first appears to simplify things, you will find it gives you much less flexibility at the cost of very few lines of boilerplate, in a language that is otherwise already very succinct.

For performance and simplicity, I recommend you just define getter methods rather than using `getproperty`. Put them on the abstract type pointing to default field names

```julia
field(p::AbstractQuantumParticle) = p.field
momentum(p::AbstractQuantumParticle) = p.momentum

```

And if you e.g. don’t need some field for a subtype, just define the same method on the subtype to return a default. You cant do that with field inheritance.

```julia
field(p::MySpecialQuantumParticle) = DefaultField()

```

This way the only boilerplate is the struct fields.

If you have too many fields, compose your objects from smaller components that can be shared between similar objects. (This is call _composition over inheritance_ and is widely recommended practice in OOP anyway. Julia just bakes it in because there is no field inheritance. [Composition over inheritance - Wikipedia](https://en.wikipedia.org/wiki/Composition_over_inheritance) Also with composition, macros like Lazy.jl `@forward` may confuse people reading your code, I personally just write out the forwarding methods)

---

<div class="post-metadata">

**Author:** ![mesonepigreco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mesonepigreco/32/46262_2.png) [@mesonepigreco](https://discourse.julialang.org/u/mesonepigreco)\
**Post date:** [August 28, 2024, 12:43pm UTC](https://discourse.julialang.org/t/structure-inheritance/118699/5 "2024-08-28T12:43:16Z")

</div>

Thank you all for the replies.

You are right; probably the best approach is to store the `QuantumParticle` inside the `Fermion` to avoid redefining its components. But then, for the function `foo(particle :: QuantumParticle)` to work with `foo(fermion)` as expected, I need to dispatch it like `foo(fermion <: Fermion) = foo(fermion.quantumparticle)`.

Indeed, combining this with getter methods might avoid dispatching all the functions implemented with `QuantumParticle`. So, I only need to dispatch the getter methods.

---

<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:** [August 28, 2024, 12:55pm UTC](https://discourse.julialang.org/t/structure-inheritance/118699/6 "2024-08-28T12:55:18Z")

</div>

> [@mesonepigreco](#):
>
> I need to dispatch it like `foo(fermion <: Fermion) = foo(fermion.quantumparticle)`.

It is hard to provide more concrete advice without specifics, but you can do stuff like

```julia
gimme_the_generic_quantumparticle(fermion::Fermion) = fermion.quantumparticle

function foo(particle)
    generic_qp = gimme_the_generic_quantumparticle(particle)
    ... # implementation here using the above
end

```

for methods that work with the generic part. You just define methods for `gimme_the_generic_quantumparticle`.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [August 29, 2024, 2:19am UTC](https://discourse.julialang.org/t/structure-inheritance/118699/7 "2024-08-29T02:19:30Z")

</div>

> [@Raf](#):
>
> I wrote [Mixers.jl](https://juliahub.com/ui/Packages/General/Mixers) to do this years ago and never use it. Most similar packages are also not widely used. While field inheritance at first appears to simplify things, you will find it gives you much less flexibility at the cost of very few lines of boilerplate

Thank you for stating this because I ran into Mixers a while ago and came to the same conclusion after a struggle, but I had a lingering suspicion I just didn’t understand how to use it. I could only accomplish method reuse for a set of fields by making an unenforceable, documented promise that an abstract type’s subtypes all share those fields, which was an abandoned idea ([abstract types with fields · Issue #4935](https://github.com/JuliaLang/julia/issues/4935)).
