# \[ANN\] CompositeStructs.jl

**URL:** <https://discourse.julialang.org/t/ann-compositestructs-jl/58902>\
**Category:** Package Announcements\
**Created:** [April 9, 2021, 4:57am UTC](https://discourse.julialang.org/t/ann-compositestructs-jl/58902 "2021-04-09T04:57:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [April 9, 2021, 4:57am UTC](https://discourse.julialang.org/t/ann-compositestructs-jl/58902/1 "2021-04-09T04:57:08Z")

</div>

While I generally view multiple-dispatch as much more powerful and flexible that object-oriented programming (see this talk [JuliaCon 2019 | The Unreasonable Effectiveness of Multiple Dispatch | Stefan Karpinski - YouTube](https://www.youtube.com/watch?v=kc9HwsxE1OY) for IMO a great explanation why), there _are_ certain object-oriented ideas I occasionally would find useful in Julia.

One of them is the ability to “inherit” fields from a “super type”. There’s a couple of packages I know about that do this ([Mixers.jl](https://github.com/rafaqz/Mixers.jl) and [Classes.jl](https://github.com/rjplevin/Classes.jl)) but both require the “super type” struct to have been decorated with a special macro, so you’re out of luck if the author didn’t do that.

[CompositeStructs.jl](https://github.com/marius311/CompositeStructs.jl) lets you “inherit” fields (by explicitly including them in your struct definition) from any number of other structs with no requirement on how these structs were defined. Unlike Classes.jl, it also lets you decide which, if any, abstract type to take as a super type. By inheriting the fields from an existing struct and opting into a well-designed abstract type hierarchy, it seems to me you can go a long way to getting the best of both worlds from multiple-dispatch and traditional OO inheritance.

The syntax is just e.g.:

```julia
struct Foo{X,Y}
    x :: X
    y :: Y
end

@composite struct Bar{X,Y,Z}
    Foo{X,Y}...
    z :: Z
end

# equivalent to defining:
struct Bar{X,Y,Z}
    x :: X
    y :: Y
    z :: Z
end

```

Another useful feature is that its compatible with `Base.@kwdef`, and the defaults from the “super type” are propagated to your new struct as well (see readme for details).

Package is registered so to install just: `pkg> add CompositeStructs`. Let me know if you run into issues and happy if anyone finds this useful.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [April 9, 2021, 6:09am UTC](https://discourse.julialang.org/t/ann-compositestructs-jl/58902/2 "2021-04-09T06:09:32Z")

</div>

Interesting idea. What is the use case you have in mind where you’d rather do `Bar(x,y,z)` than [keep the interfaces distinct with composition](https://www.youtube.com/watch?v=3MNVP9-hglc) `Bar(Foo(x,y),z)`?

---

<div class="post-metadata">

**Author:** ![xzackli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xzackli/32/38301_2.png) [@xzackli](https://discourse.julialang.org/u/xzackli)\
**Post date:** [April 9, 2021, 6:20am UTC](https://discourse.julialang.org/t/ann-compositestructs-jl/58902/3 "2021-04-09T06:20:34Z")

</div>

Looking forward to using this with `Base.@kwdef`. I have big immutable parameter structs with 10-30 parameters, and I expect this will make it much less verbose when defining a new concrete type with the same abstract parent type.

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [April 9, 2021, 6:34am UTC](https://discourse.julialang.org/t/ann-compositestructs-jl/58902/4 "2021-04-09T06:34:05Z")

</div>

> [@jzr](#):
>
> What is the use case you have in mind where you’d rather do `Bar(x,y,z)` than [keep the interfaces distinct with composition](https://www.youtube.com/watch?v=3MNVP9-hglc) `Bar(Foo(x,y),z)` ?

I think its probably a pretty similar use case, just a slightly different way to go about it. Sometimes to me the lines get pretty blurry between “does Bar _have_ a Foo or is Bar a modified _kind of_ Foo” and this package is if you’re leaning the latter. For the former, if you do want Bar to behave like a Foo in some scenarios, you will probably still need something like “delegation” (I found [this thread](https://discourse.julialang.org/t/method-forwarding-macro/23355) informative) so in some sense this package takes the place of those if you choose to go this route.
