# Property Inheritance Pattern

**URL:** https://discourse.julialang.org/t/property-inheritance-pattern/40101
**Category:** General Usage
**Tags:** inheritance, structtypes
**Created:** [May 25, 2020, 2:34am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101 "2020-05-25T02:34:12Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 2:34am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/1 "2020-05-25T02:34:12Z")

</div>

As of version 1.4 Julia does not support property inheritance. However, many other languages such as Python do support inheritance and porting libraries from these languages becomes difficult.

I am proposing an informal design pattern to enable type inheritance for this purpose. The goals are to:

- Not require external dependencies
- Minimize boilerplate as much as possible
- Maintain dot-syntax property accessors
- Follow encapsulation principals. That is changes to one type should only require modifying that one type and should not require having to update subtypes or cause a cascade of changes.

Please provide feedback if you think this method is flawed, unnecessary, or needs improvement.

For each concrete type `Foo` there should be two abstract types associated with it `AbstractFoo` and `FooSubtype`.

The `AbstractFoo` represents `Foo` and all if it’s subtypes. Methods of `Foo` should have `AbstractFoo` as their first parameter.

`FooSubtype` represents only the subtypes of `Foo`. This is used to create property getters and setters for the subtypes.

Here is the structure of this pattern:

```julia
abstract type AbstractFoo end

mutable struct Foo <: AbstractFoo
    a::String
    Foo(a) = new(a)
end

say_something(foo::AbstractFoo) = println(foo.a)

abstract type FooSubtype <: AbstractFoo end

Base.getproperty(sub::FooSubtype, s::Symbol) = get(sub, Val(s))
# In the base-type, a fallback accessor is defined
get(sub::FooSubtype, ::Val{T}) where {T} = getfield(sub, T)
get(sub::FooSubtype, ::Val{:a}) = sub.foo.a

Base.setproperty!(sub::FooSubtype, s::Symbol, x) = set!(sub, Val(s), x)
# In the base-type, a fallback accessor is defined
set!(sub::FooSubtype, ::Val{T}, x) where {T} = setfield!(sub, T, x)
set!(sub::FooSubtype, ::Val{:a}, x) = sub.foo.a = x

abstract type AbstractBar <: FooSubtype end

mutable struct Bar <: AbstractBar
    foo::Foo
    b::String
    Bar(a, b) = new(Foo(a), b)
end

say_something(bar::AbstractBar) = println("$(bar.a) $(bar.b)")

abstract type BarSubtype <: AbstractBar end

Base.getproperty(sub::BarSubtype, s::Symbol) = get(sub, Val(s))
# In a sub-type, a getter to the super-type object is defined
get(sub::BarSubtype, ::Val{:foo}) = sub.bar.foo
get(sub::BarSubtype, ::Val{:b}) = sub.bar.b

Base.setproperty!(sub::BarSubtype, s::Symbol, x) = set!(sub, Val(s), x)
set!(sub::BarSubtype, ::Val{:b}, x) = sub.bar.b = x

abstract type AbstractBaz <: BarSubtype end

mutable struct Baz <: AbstractBaz
    bar::Bar
    c::String
    Baz(a, b, c) = new(Bar(a, b), c)
end

say_something(baz::AbstractBaz) = println("$(baz.a) $(baz.b) $(baz.c)")

abstract type BazSubtype <: AbstractBaz end

Base.getproperty(sub::BazSubtype, s::Symbol) = get(sub, Val(s))
# In a sub-type, a getter to the super-type object is defined
get(sub::BazSubtype, ::Val{:bar}) = sub.baz.bar
get(sub::BazSubtype, ::Val{:c}) = sub.baz.c

Base.setproperty!(sub::BazSubtype, s::Symbol, x) = set!(sub, Val(s), x)
set!(sub::BazSubtype, ::Val{:c}, x) = sub.baz.c = x

foo = Foo("Foo")
say_something(foo)

bar = Bar("Foo", "Bar")
say_something(bar)

baz = Baz("Foo", "Bar", "Baz")
say_something(baz)

baz.a = "FOO"
baz.b = "BAR"
baz.c = "BAZ"
say_something(baz)

```

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [May 25, 2020, 2:36am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/2 "2020-05-25T02:36:43Z")

</div>

What do you mean by type ineritence? Methods in Julia can be written to accept subtypes of a type, so I’m kind of confused by what problem this is designed to solve.

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 2:38am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/3 "2020-05-25T02:38:08Z")

</div>

I guess mainly the problem of property inheritance. Sub types do not inherit the properties of their super types. A naive approach to solving this problem would lead to massive amounts of code duplication. For example in an object oriented package im currently porting, the base class maintains allot of internal state. None of which needs to be seen by sub-classes. If all the sub-classes had to carry this over it would become very cumbersome. However, the method i purpose is also cumbersome, but could be simplified with a macro.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [May 25, 2020, 2:49am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/4 "2020-05-25T02:49:25Z")

</div>

It sounds like a simple approach would be to create a `struct InternalState` which all subtypes have as a field (if they want).

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 3:12am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/5 "2020-05-25T03:12:43Z")

</div>

That is a possible solution. It would require each subtype have a copy of each of its supertype’s InternalState. And it would probably not be optional since methods from the base type will still need access to each of them. But i’m not sure how initialization logic would work in that case. Could the initializer of each internal state be encapsulated, such that you would not have to rewite the logic from the base initializer each time, especially of there is allot of complex initialization logic? But I do see that were dealing with edge cases and not the typical type inheritance scenario.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 5:44am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/6 "2020-05-25T05:44:50Z")

</div>

> [@virtualgraham](#):
>
> Sub types do not inherit the properties of their super types.

More than that: supertypes can’t even have any fields to inherit, because only concrete types can have fields, while only abstract types can be supertypes.

This makes your proposal a bit hard to read, since it appears confused on that point. But, as far as I understand, you’re not suggesting any changes to Julia, just showing a way of using composition to mimick inheritance?

As for

> [@virtualgraham](#):
>
> the base class maintains allot of internal state.

do you mean that an object of the supertypes maintains the state, or the class itself. Classes can hold state in Python, but not in Julia.

> [@virtualgraham](#):
>
> It would require each subtype have a copy of each of its supertype’s InternalState.

Can’t they all hold a reference to the same object, why copies?

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 6:09am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/7 "2020-05-25T06:09:25Z")

</div>

Im not suggesting any changes to Julia because libraries written from scratch can generally avoid this problem. But for me this is a problem when porting a library that has been written in a more traditional object oriented (OO) language and you don’t want to completely redesign everything. Even then i think @Oscar_Smith’s solution is fine most of the time.

> [@DNF](#):
>
> Can’t they all hold a reference to the same object, why copies?

Perhaps copies was the wrong word. But, depending how far down the inheritance tree a type is, subtypes would need to have one `InternalState` property defined for each super type.

```julia
abstract type AbstractFoo end

mutable struct FooInternal
   a
   # A lot more internal state properties
end

mutable struct Foo <: AbstractFoo
   foo_internal::FooInternal
end

abstract type AbstractBar <: AbstractFoo end

mutable struct BarInternal <: AbstractBar
   b
   # A lot more internal state properties
end

mutable struct Bar
   foo_internal::FooInternal
   bar_internal::BarInternal
end

# a will always be accecable at .foo_internal.a without having to copy and paste 
# a lot of internal state properties for every subtype
say_something(foo::AbstractFoo) = println(foo.foo_internal.a)
say_something(bar::AbstractBar) = println("$(foo.foo_internal.a) $(bar.bar_internal.a)")

```

But my idea came from trying to make the type system a bit more OO like. So in traditional OO each object will have a `super` which will encapsulate the properties of the super type. On this forum people have suggested such a pattern for Julia:

```julia
mutable struct Foo
    a
end

mutable struct Bar
   b
   foo::Foo
end

mutable struct Baz
   c
   bar::Bar
end

get_a(foo::Foo) foo.a
get_a(bar::Bar) bar.foo.a
get_a(baz::Baz) baz.bar.foo.a

```

But the problem with that is when accessing `a` from `Bar` you have to use `bar.foo.a` This makes `Bar` incompatible with methods that call `foo.a`. So the naive solution for that is to have assessor methods.

`get_a(bar::Bar) = bar.foo.a`

Other than being annoying having to use `get_a(bar)` instead of `bar.a` this also creates the problem that you have to define all the accessor methods for `Foo` inside `Bar` and and do it agian if you want a `Baz` even if the property was only ever used by a method for Foo

My proposed pattern allows for a more traditional OO structure that makes for a more direct translation from OO languages. You can keep all the dot notation. Object initialization logic can remain intact without having to reuse initialization code in sub-types. And types stay mostly encapsulated. If you have a file that defines an object `Foo` with a property `a` that is never used in subclasses then it should be possible to write a second file for `Bar` that does not have to deal with `a`. And if later `a` is changed or removed, `Bar` is unaffected.

So you could do something like:

```julia
mutable struct Foo
   n
   large_array
   Foo(n) = new(n, zeros(n))
end

mutable struct NamedFoo
   foo::Foo
   name
   # we don't need to initialize large_array or worry about its implementation here
   NamedFoo(n, name) = new(Foo(n), name)
end

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 6:58am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/8 "2020-05-25T06:58:38Z")

</div>

> [@virtualgraham](#):
>
> Perhaps copies was the wrong word. But, depending how far down the inheritance tree a type is, subtypes would need to have one `InternalState` property defined for each super type.
> 
> ```julia
> [snip]
> mutable struct Bar
> foo_internal::FooInternal
> bar_internal::BarInternal
> end
> 
> ```

But this seems to be an example of _multiple_ inheritance. That’s orthogonal to how far things are down the inheritance tree. Naturally, you N supertype-fields for N supertypes (or perhaps a tuple of supertype objects.)

> [@virtualgraham](#):
>
> ```julia
> get_a(bar::Bar) = bar.foo.a
> 
> ```

Wouldn’t you just use

```julia
function getproperty(baz::Baz, sym)
    if sym == :a
        return baz.bar.a
    else
        ...
    end
end

```

and then `Bar` would have a similar definition, and it would cascade to the top level.

Or, even, more lazily

```julia
function getproperty(x::AbstractToplevelType, sym)
    if sym == :a
        if hasfield(x, sym)
            return x.a
        else
            return x.super.a
        end
    else
        ...
    end
end

```

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 7:04am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/9 "2020-05-25T07:04:19Z")

</div>

> [@DNF](#):
>
> ```julia
> function getproperty(x::AbstractToplevelType, sym)
> if sym == :a
> if hasfield(x, sym)
> return x.a
> else
> return x.super.a
> end
> else
> ...
> end
> end
> 
> ```

Basically this is exactly what im doing except differently. I guess performance wise I would have to try both. Mine uses multiple dispatch and yours uses if else statement. As far as simplicity yours is better.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 7:22am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/10 "2020-05-25T07:22:04Z")

</div>

> [@virtualgraham](#):
>
> Basically this is exactly what im doing except differently.  
> […]  
> `get_a(baz::Baz) baz.bar.foo.a`

This seems really different to me. You have to implement the full chain to the top for each type, instead of just recursively deferring to the supertype. Also, you use a special `get_a` instead of `getproperty` which you appeared to be dissatisfied with:

> [@virtualgraham](#):
>
> Other than being annoying having to use `get_a(bar)` instead of `bar.a` this also creates the problem that you have to define all the accessor methods for `Foo` inside `Bar` and and do it agian if you want a `Baz` even if the property was only ever used by a method for Foo

The way I’m suggesting, simply writing `baz.a` will work directly, no matter how many levels down you are.

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 7:25am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/11 "2020-05-25T07:25:12Z")

</div>

`get_a(baz::Baz) baz.bar.foo.a` was my counter example, to show what was a _bad_ idea.

See the code example in the initial post for the full example but what i do think might be a _good_ idea is this:

```julia
abstract type FooSubtype <: AbstractFoo end

Base.getproperty(sub::FooSubtype, s::Symbol) = get(sub, Val(s))
# In the base-type, a fallback accessor is defined
get(sub::FooSubtype, ::Val{T}) where {T} = getfield(sub, T)
get(sub::FooSubtype, ::Val{:a}) = sub.foo.a

Base.setproperty!(sub::FooSubtype, s::Symbol, x) = set!(sub, Val(s), x)
# In the base-type, a fallback accessor is defined
set!(sub::FooSubtype, ::Val{T}, x) where {T} = setfield!(sub, T, x)
set!(sub::FooSubtype, ::Val{:a}, x) = sub.foo.a = x

```

This is basically the multiple dispatch version of what you suggested earlier

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 7:31am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/12 "2020-05-25T07:31:16Z")

</div>

OK, I missed that. Should read your post over more carefully later.

But it seems annoying to have to use a special `get` function instead of `getproperty`. Performance for my version shouldn’t be any worse, I think.

---

<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: [May 25, 2020, 7:33am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/13 "2020-05-25T07:33:19Z")

</div>

The semantics of Julia favor _composition_ over _inheritance_.

Search the forum for previous discussions, or the web for a broader context.

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 7:34am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/14 "2020-05-25T07:34:26Z")

</div>

I found that pattern here [Getproperty, decorations, inheritance in 0.7 - #3 by fredrikekre](https://discourse.julialang.org/t/getproperty-decorations-inheritance-in-0-7/11237/3)

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 7:37am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/15 "2020-05-25T07:37:49Z")

</div>

I know there has been many threads discussing proposals to implement inheritance. But im just trying to find a method to simplify the porting of object oriented code.

---

<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: [May 25, 2020, 7:44am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/16 "2020-05-25T07:44:09Z")

</div>

I don’t think that a 1:1 port of code from an OO language is a reasonable goal. Julia works differently.

Coming up with an idiomatic organization of the code and the API usually has a lot of additional benefits.

---

<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: [May 25, 2020, 8:07am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/17 "2020-05-25T08:07:18Z")

</div>

While I agree with @Tamas_Papp that a straight porting from Python may not be optimal, you may take advantage of several packages providing Julia macros to simulate OOP patterns to a certain extent.

One such package is [ReusePatterns](https://github.com/gcalderone/ReusePatterns.jl), allowing both composition and concrete subtyping.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 8:37am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/18 "2020-05-25T08:37:28Z")

</div>

I think that using a lot of value types has fallen a bit out of favour since v1.0, as constant propagation has become more powerful. I don’t think there are any advantages to using them instead of simple branches inside `getproperty`, and it’s probably a bit harder to read too.

One detail, though.

> [@virtualgraham](#):
>
> ```julia
> get(sub::FooSubtype, ::Val{T}) where {T} = getfield(sub, T)
> set!(sub::FooSubtype, ::Val{T}, x) where {T} = setfield!(sub, T, x)
> 
> ```

Your fallbacks could be simpler, I think they don’t need the type signatures:

```julia
get(sub::FooSubtype, s) = getfield(sub, s)
set!(sub::FooSubtype, s, x) = setfield!(sub, s, x)

```

---

<div class="post-metadata">

### Author: ![virtualgraham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/virtualgraham/32/15200_2.png) [@virtualgraham](https://discourse.julialang.org/u/virtualgraham)
#### Post date: [May 25, 2020, 10:00am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/19 "2020-05-25T10:00:55Z")

</div>

Here is a version I tested that only requires extending a top level type `Object` and having a field `super` in all the subtypes. It will recurse up the type hierarchy searching for the property:

```julia
abstract type Object end

function Base.getproperty(o::Object, s::Symbol)
    t = typeof(o)
    if hasfield(t, s) 
        return getfield(o, s)
    elseif hasfield(t, :super)
        return getproperty(getfield(o, :super), s)
    end
end

function Base.setproperty!(o::Object, s::Symbol, x)
    t = typeof(o)
    if hasfield(t, s) 
        setfield!(o, s, x)
    elseif hasfield(t, :super)
        setproperty!(getfield(o, :super), s, x)
    end
end

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [May 25, 2020, 10:39am UTC](https://discourse.julialang.org/t/property-inheritance-pattern/40101/20 "2020-05-25T10:39:43Z")

</div>

> [@virtualgraham](#):
>
> `elseif hasfield(t, :super)`

I don’t think this test should be done. `t` _should_ have a field called `super`, and if it doesn’t, you _should_ get an error. Right now, it would just do nothing.

And isn’t it a bit overly verbose? I think this should work as well:

```julia
function Base.getproperty(o::Object, s::Symbol)
    if hasfield(typeof(o), s) 
        return getfield(o, s)
    end
    return o.super.s
end

function Base.setproperty!(o::Object, s::Symbol, x)
    if hasfield(typeof(o), s) 
        setfield!(o, s, x)
    else
        o.super.s = x
    end
end

```

[Next page](https://discourse.julialang.org/t/property-inheritance-pattern/40101.md?page=2)
