# Composition and inheritance: the Julian way

**URL:** <https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231>\
**Category:** General Usage\
**Tags:** inheritance, structtypes\
**Created:** [May 29, 2018, 1:06pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231 "2018-05-29T13:06:00Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 3:45pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/62 "2018-06-01T15:45:25Z")

</div>

> [@ChrisRackauckas](#):
>
> Now just forward the array interface onto `x` and you’re good.

The key point here is the word **just**. For a simple example you’re definitely right. But for a real life application (such as wrapping a `DataFrame` object as we discussd above) this implies redefining ~200 methods. Of course a few of these (namely all those returning a `DataFrame` struct) have to be redefined anyway, but what remains is still quite a large number.

Of course this is feasible, either manually or through macros, but my first thought is that I should try to find an alternative method. This triggered all present discussion.

> [@ChrisRackauckas](#):
>
> Arrays are primitives in Julia so you can’t access their data

Yeah, clearly all what we say here applies only if a structure is involved.

> [@ChrisRackauckas](#):
>
> You can always fight against this oncoming train,

Of course I don’t want to fight any train. I’m asking here because I recognize many here are as way more expert than me. Still: no one told me **yes, you have to blindly forward those ~200 methods, and forget about inheritance**.

Which is OK for me, but I didn’t saw this carved in stones, nor in the manual or in the discourse or anywhere else. Hence my doubt arose…

To answer @favba: in your proposal you are implementing the `name`, `age` and `set_age` for both `Person` and `Citizen`, which is exactly what I wanted to avoid (the famous ~200 methods…). Regardless of macro usage: the methods are always there: they do nothing, they flood the dispatch table and they have to be compiled.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 3:54pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/63 "2018-06-01T15:54:39Z")

</div>

Thanks @ScottPJones!!!  
You’re solution is definitely a very interesting one, and I think it definitely solve the problem in the first discussion of this post. You’re great!! 👍👍

In brief, your solution uses composition of structures and avoid useless methods re-definition.  
Clearly, as noted by @ChrisRackauckas, there are quite a lot of `getproperty` calls involved. However (correct me if I’m wrong) there are quite a lot of `getproperty` calls involved also in method forwarding isn’t it?

---

<div class="post-metadata">

**Author:** ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)\
**Post date:** [June 1, 2018, 3:57pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/64 "2018-06-01T15:57:08Z")

</div>

One apparently officially questionable way is discussed in [https://discourse.julialang.org/t/getproperty-decorations-inheritance-in-0-7/11237](https://discourse.julialang.org/t/getproperty-decorations-inheritance-in-0-7/11237).

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [June 1, 2018, 3:59pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/65 "2018-06-01T15:59:37Z")

</div>

> [@gcalderone](#):
>
> The key point here is the word **just**. For a simple example you’re definitely right. But for a real life application (such as wrapping a `DataFrame` object as we discussd above) this implies redefining ~200 methods. Of course a few of these (namely all those returning a `DataFrame` struct) have to be redefined anyway, but what remains is still quite a large number.

No, you don’t have to. If your interface on the abstract type is done via accessor functions (or lazy properties), then the interface to implement is tiny and limited to defining those accessor functions. See something like the AbstractArray interface which takes

[https://docs.julialang.org/en/v0.6.2/manual/interfaces/#man-interface-array-1](https://docs.julialang.org/en/v0.6.2/manual/interfaces/#man-interface-array-1)

and then works in literally any function which takes arrays. This is because if you develop code for the abstract type based on the interface (and it doesn’t have to be an abstract type, for example the Iteration Interface is for anything which acts like an iterable) then any implementation of that interface will do. If all of Julia’s arrays can work with 5 methods plus some extra traits, then that shows there’s quite a lot you can do.

If your interface is 200+ methods, it doesn’t matter if it’s Julia or OOP, you’re doing it wrong!

Dataframes is a bad example because they never defined an interface for a Dataframe which is why it’s so hard to extend. If you want a table interface, look at DataStreams.jl or IterableTables.jl. These have only a handful of functions and any source/sink will then work as a table. For example, Dataframes implements the source while StatPlots.jl implements the sink, so those two packages work together. But DifferentialEquations.jl solutions are also a sink, so you can convert its solutions to Dataframes or use it just like a table due to the 3 methods implemented by David. So, 200 methods \>\> the 3 that are used in the real live actually working example 😄.

Here’s the full code that makes every differential equation solution (ODE/SDE/DAE/DDE/jump/etc.) have a table interface and directly convert to DataFrames.

[https://github.com/JuliaDiffEq/DiffEqBase.jl/blob/master/src/tabletraits.jl](https://github.com/JuliaDiffEq/DiffEqBase.jl/blob/master/src/tabletraits.jl)

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 3:59pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/66 "2018-06-01T15:59:48Z")

</div>

Now the bad news: despite the very clever suggestion by @ScottPJones this solution can not be applied in general, since it works only if the object you wish to extend/customize already uses the `person(a::Person) = a` method internally, which doesn’t apply to `DataFrame`…

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [June 1, 2018, 4:02pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/67 "2018-06-01T16:02:51Z")

</div>

It seems that there are two tasks, then for `DataFrames`, if you were to create a new type for metadata (which you don’t have to do! maintainers seem amenable to metadata living in DataFrames)

First, make sure `DataFrames` methods only take in `AbstractDataFrame`. Second, categorize which functions absolutely need to be defined toe `AbstractDataFrame` to work. Maybe there already exists a list somewhere? Or we could work on getting that list together and shortened. A good start would be to create a new `MyDataFrame <: AbstractDataFrame` type that is a mirror image of a `DataFrame` type and seeing how that works.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [June 1, 2018, 4:06pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/68 "2018-06-01T16:06:46Z")

</div>

> [@pdeffebach](#):
>
> First, make sure `DataFrames` methods only take in `AbstractDataFrame` . Second, categorize which functions absolutely need to be defined toe `AbstractDataFrame` to work. Maybe there already exists a list somewhere? Or we could work on getting that list together and shortened. A good start would be to create a new `MyDataFrame <: AbstractDataFrame` type that is a mirror image of a `DataFrame` type and seeing how that works.

> **[GitHub - queryverse/IterableTables.jl: Implementations of the TableTraits.jl...](https://github.com/queryverse/IterableTables.jl)**
>
> Implementations of the TableTraits.jl interface for various packages - GitHub - queryverse/IterableTables.jl: Implementations of the TableTraits.jl interface for various packages

> **[GitHub - JuliaData/DataStreams.jl: \[DEPRECATED in favor of...](https://github.com/JuliaData/DataStreams.jl)**
>
> \[DEPRECATED in favor of https://github.com/JuliaData/Tables.jl\] A fast, generic framework for transferring table-like data structures in Julia - GitHub - JuliaData/DataStreams.jl: \[DEPRECATED in fa...

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 4:07pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/69 "2018-06-01T16:07:45Z")

</div>

> [@ChrisRackauckas](#):
>
> Dataframes is a bad example because they never defined an interface for a Dataframe which is why it’s so hard to extend

…and this provides a motivation for the second part of the question. thank you for clarifying! 👍

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 4:14pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/70 "2018-06-01T16:14:00Z")

</div>

> [@pdeffebach](#):
>
> (which you don’t have to do! maintainers seem amenable to metadata living in DataFrames)

Good to know. Actually, there already is a [PR](https://github.com/JuliaData/DataFrames.jl/pull/1413) for this, although it has been assigned no reviewer yet…

> [@pdeffebach](#):
>
> First, make sure `DataFrames` methods only take in `AbstractDataFrame` . Second, categorize which functions absolutely need to be defined toe `AbstractDataFrame` to work. Maybe there already exists a list somewhere? Or we could work on getting that list together and shortened. A good start would be to create a new `MyDataFrame <: AbstractDataFrame` type that is a mirror image of a `DataFrame` type and seeing how that works.

Yeah, I can try to do it if some of the maintainers manifest their wish to go in that direction, so that there is some chance that I will not waste my time in a PR which will surely be rejected.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [June 1, 2018, 4:57pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/71 "2018-06-01T16:57:14Z")

</div>

So it appears we’re finally figuring out a solution to the problem here. I will try to summarize:

- the problem arose trying to extend/customize the behaviour of a Julia object (i.e. a structure+methods, call it `Person`) into another one (call it `Citizen`) in a way that it can be used exactly as the base type, except for a few _twist_ (i.e. specialized methods);

- we wanted to solve this problem minimizing as much as possible the number of methods redefined just to forward calls to the base type;

- minimizing this number implies we had to implement an inheritance-like approach to the problem, and we identified a few rules to be followed ([here](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/25) and [here](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/42));

- the inheritance-like approach, however, turned out to be non convenitent as discussed by @ChrisRackauckas [here](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/45) and [here](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/53). The best, and more _Julian_ way to face this problem is by means of composition, regardless of the number of method to be re-defined;

- @ScottPJones found what I think is a very nice approach [here](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/60) which uses both composition (in place of inheritance) and minimizes the number of method re-definitions. However, this method requires to re-write the methods in the base class;

- The real interest for this discusion was the possibility to customize a `DataFrame` object (further discussion [here](https://discourse.julialang.org/t/how-to-add-metadata-info-to-a-dataframe/11168/57)) and refactor the whole package following @ScottPJones solution is not feasible;

- @ChrisRackauckas provided the last piece of information: the `DataFrame` still lacks the definition of an interface which simplifies extending it. Here’s why we had all the problems which ultimately triggered this discussion.

The whole story was absolutely not clear to me when I first started this post, and I’m sorry if everything was obvious to many people here. I learned a lot and wish to thank all of you! :+1

---

<div class="post-metadata">

**Author:** ![Liso](https://avatars.discourse-cdn.com/v4/letter/l/898d66/32.png) [@Liso](https://discourse.julialang.org/u/Liso)\
**Post date:** [June 2, 2018, 8:49am UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/72 "2018-06-02T08:49:59Z")

</div>

I am curious if @ScottPJones’s method could be formalized. By methodology or by language (macros) support.

I am also curious if it will make negative performance impact comparing to “slavery” work with ~200 methods rewrite.

Scott’s method allow multiple inheritance too! (So it could also bring many problems which multiple inheritance use to bring)

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [January 14, 2019, 5:24pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/73 "2019-01-14T17:24:42Z")

</div>

Dear all,  
this topic has been inactive for a few months, but I just wanted to add that I implemented a package to solve the first problem posted, namely how to implement some form of _inheritance_ mechanism in Julia.

Actually, the solution is to implement [subtyping](https://en.wikipedia.org/wiki/Subtyping) which, although not equivalent to inheritance (e.g. [here](https://en.wikipedia.org/wiki/Subtyping#Relationship_with_inheritance)), allows to quickly and elegantly solve the problem.

The trick is to unambiguously link an abstract type and a concrete one, realizing a kind of _quasi-abstract_ type. Then we can use the latter as argument type for methods: it is both an abstract type (allowing the same method to be called on subtypes) and a concrete one (ensuring the method will receive the appropriate concrete structure). A macro can then takes care of copy/pasting the fields from one quasi-abstract\* type to another, realizing a **concrete subtyping** pattern.

The details are discussed in the README.md file of the [ReusePatterns](https://github.com/gcalderone/ReusePatterns.jl) package.

The implementation of concrete subtyping for the first example in this post is as follows:

```julia
using ReusePatterns

#---------------------------------------------------------------------
# BASE TYPE : Person
@quasiabstract mutable struct Person
    name::String
    age::Int
end
Person(name) = Person(name, 0)
Base.display(p::Person) = println("Person: ", p.name, " (age: ", p.age, ")")

function happybirthday(p::Person)
    p.age += 1
    println(p.name, " is now ", p.age, " year(s) old")
end

call(p::Person) = print(uppercase(p.name), "!")

son(p::Person) = Person(p.name * " junior", 0)

# EXAMPLES
p = Person("Giorgio")
happybirthday(p)
call(p)
call(son(p))

#---------------------------------------------------------------------
# DERIVED TYPE : Citizen
@quasiabstract mutable struct Citizen <: Person
    nationality::String # new field
end

# Note that the fields associated to `Citizen` automatically include those from `Person`
println(fieldnames(concretetype(Citizen)))

function call(p::Citizen)
    if p.nationality == "Italian"
        print(uppercase(p.name), " dove sei ?")
    elseif p.nationality == "UK"
        print(uppercase(p.name), " where are you ?")
    else
        invoke(call, Tuple{supertype(Citizen)}, p)
    end
end

Citizen(name, nationality) = Citizen(name, 0, nationality)

function son(p::Citizen)
    person = Person(getfield.(Ref(p), fieldnames(concretetype(Person)))...)
    return Citizen(person.name * " junior", 1, p.nationality)
end

p = Citizen("Giorgio", "Italian")
happybirthday(p)
call(p)
call(son(p))

p = Citizen("Kim", "UK")
happybirthday(p)
call(p)
call(son(p))

p = Citizen("Jean", "French")
happybirthday(p)
call(p)
call(son(p))

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 14, 2019, 8:54pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/74 "2019-01-14T20:54:30Z")

</div>

There are also the packages `ConcreteAbstractions.jl` and `Classes.jl` that do similar things.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [January 14, 2019, 10:02pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/75 "2019-01-14T22:02:54Z")

</div>

Yes, I cited both packages in the links section of [ReusePatterns](https://github.com/gcalderone/ReusePatterns.jl), in order to encourage the users to check for similar functionalities.

However, `ConcreteAbstraction.jl` seems to be unmaintained.  
`Class.jl` is alive, and the main difference is that it operates in several points in the user code (once in the structure definition and once for each method) while `ReusePatterns` provides just one macro (`@quasiabstract`) to be used in the structure definition. Moreover, `ReusePatterns` aims also to provide a direct comparison with the _composition_ pattern, to check which one provides the best solution.

Finally, it provides a (hopefully) useful discussion on the rationale behind the _composition_ and _concrete subtyping_ approaches. It is surely due to my ignorance, but when I first started this post I was not aware of the many subtleties involved, and if I had the opportunity to read something like the [README.md](https://github.com/gcalderone/ReusePatterns.jl/blob/master/README.md) which is now available in `ReusePatterns` I would not have started this post… 😉

---

<div class="post-metadata">

**Author:** ![Orbots](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/orbots/32/3392_2.png) [@Orbots](https://discourse.julialang.org/u/Orbots)\
**Post date:** [January 14, 2019, 11:39pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/76 "2019-01-14T23:39:45Z")

</div>

By a quick count in this thread, there are 5+ packages to help solve this problem. Curious if there is anything in the Julia roadmap or comments by the developers on addressing this in the language ( or Base/Standard Library)? While packages are nice, it seems there is a strong case for it to be addressed in the core language ( even if it’s just in the documentation ).

As a bit of an aside, I find the concept of traits extremely useful in arriving at an optimal Julian solution. I often start implementing trait-based dispatch only to find a refactor of my types/functions that does the same thing without traits.

---

<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:** [January 15, 2019, 12:56am UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/77 "2019-01-15T00:56:48Z")

</div>

A few questions!

What’s the connection between `@forward` and `@quasiabstract`? I may misunderstand but it seems like this would also make sense as two packages, one for composition and one for concrete subtyping? I’ve always thought there should be a Forward package that just does `@forward` macros well.

I also use Mixers.jl for field/type/macro inheritance and traits take care of method inheritance for the mixin. What would I gain from switching to quasiabstract inheritance? The looseness of using mixins does bother me occasionally but it has the advantage of being very simple and applicable on unrelated branches of an abstract type hierarchy.

Edit: Also how does concrete subtyping play with Parameters.jl or FieldMetadata.jl style macros where struct fields are annotated?

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [January 15, 2019, 1:56am UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/78 "2019-01-15T01:56:37Z")

</div>

Another recent package for inheritance that is not mentioned in this thread. Is one I have been working on `StructuralInheritance.jl`.

It works by creating a concrete type and an abstract type which is used to inherit behavior. It stores the fields that are defined with fully qualified types and splices it into inheriting types.

```julia
julia> using StructuralInheritance

julia> import StructuralInheritance: totuple #used for immitating superconstructors

julia> @protostruct struct A
           firstFieldFromA::Int
           second::Float64
       end
ProtoA

julia> @protostruct struct B <: A
           yetAnotherFieldName::Float64
       end "SomeOtherPrefix"
SomeOtherPrefixB

julia> @doc B
  No documentation found.

  Summary
  ≡≡≡≡≡≡≡≡≡

  struct B <: SomeOtherPrefixB

  Fields
  ≡≡≡≡≡≡≡≡

  firstFieldFromA :: Int64
  second :: Float64
  yetAnotherFieldName :: Float64

  Supertype Hierarchy
  ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

  B <: SomeOtherPrefixB <: ProtoA <: Any

```

super constructors can also be imitated

```julia
julia> A(x) = A(x^5,x^(-1.0))
A

julia> B(x) = B(totuple(A(x))...,x)
B

```

Functions defined on the abstract type that is created with A, will work with anything that uses `@protostruct` to inherit from A or any of its descendants.

```julia
julia> dosomething(x::ProtoA) = x.firstFieldFromA * x.second
dosomething (generic function with 1 method)

julia> B(2)
B(32, 0.5, 2.0)

julia> dosomething(B(2))
16.0

```

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [January 16, 2019, 2:24pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/79 "2019-01-16T14:24:53Z")

</div>

> [@Orbots](#):
>
> While packages are nice, it seems there is a strong case for it to be addressed in the core language (even if it’s just in the documentation ).

I agree: we need to formalize the way we approach the problem, and document it once and for all. As I said above, the most useful part of `ReusePatterns.jl` is probably its README.md file…

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [January 16, 2019, 2:28pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/80 "2019-01-16T14:28:18Z")

</div>

> [@Raf](#):
>
> What’s the connection between `@forward` and `@quasiabstract` ? I may misunderstand but it seems like this would also make sense as two packages, one for composition and one for concrete subtyping?

Both `@forward` and `@quasiabstract` allow to implement reusing patterns. But what is the best pattern depends on the problem and the boundary conditions (i.e. if Alice and Bob talks to each other…).

Hence it makes sense to provide them in a single package to facilitate switch back and forth, and to provide a clear comparison of the approaches in the examples.

> [@Raf](#):
>
> I’ve always thought there should be a Forward package that just does `@forward` macros well.

AFAIK, the `@forward` macro in `ReusePatterns.jl` is the only one which automatically forwads all the necessary methods.

> [@Raf](#):
>
> I also use Mixers.jl for field/type/macro inheritance and traits take care of method inheritance for the mixin. What would I gain from switching to quasiabstract inheritance?

I’m not sure you will gain anything operationally or in terms of performance. As I said several similar functionalities are provided by other packages.

The point is: do you simply want your code to work, or do you wish to follow a (hopefully) well thought approach (even if it doesn’t provide any practical advantage) ? In the former case you may choose any package you like. In the latter case I suggest you to give `Reusepatterns.jl` a try, and if you find some flaw in the _reasoning_ please tell me. I’m way more interested in understanding **how** it should be done, rather than in the implementation itself.

---

<div class="post-metadata">

**Author:** ![gcalderone](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gcalderone/32/1539_2.png) [@gcalderone](https://discourse.julialang.org/u/gcalderone)\
**Post date:** [January 16, 2019, 3:00pm UTC](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231/81 "2019-01-16T15:00:33Z")

</div>

> [@Raf](#):
>
> Also how does concrete subtyping play with Parameters.jl or FieldMetadata.jl style macros where struct fields are annotated?

I just gave it a try, and unfortunately it doesn’t work.

As far as I understand both `@with_kw` and `@metadata` are just convenience macros, although complex. On the other hand the code generated by `@quasiabstract` is very simple (see the examples), hence if you should use them all toghether I would simply avoid using the `quasiabstract` macro, and do typing by hand.

As I stated above, the main purpose of `ReusePatterns` is to propose standard patterns for code reuse, not necessary implemented with `ReusePatterns`.

If concrete subtyping should gain popularity I may consider the idea of making `ReusePattern` compatible with other widely used packages. As always PR are more than welcome… 😉

[Previous page](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231.md?page=3)

[Next page](https://discourse.julialang.org/t/composition-and-inheritance-the-julian-way/11231.md?page=5)
