# Can I impose a super type for an existing struct?

**URL:** <https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460>\
**Category:** General Usage\
**Created:** [November 2, 2020, 2:51pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460 "2020-11-02T14:51:10Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 2, 2020, 2:51pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/1 "2020-11-02T14:51:10Z")

</div>

As per title, can I impose my

```julia
abstract type MyAbstractType end

```

as a/the supertype for a pre-existing struct/type `ExistingStruct` coming from, say, a separate module? I just want

```julia
ExistingStruct <: MyAbstractType

```

to return `true`.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 2:52pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/2 "2020-11-02T14:52:35Z")

</div>

No. Can you describe the situation in which this is needed, so we can suggest alternatives?

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 2, 2020, 3:00pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/3 "2020-11-02T15:00:06Z")

</div>

I have an abstract type `InitialValueProblem` and a function (a solver) that takes any concrete subtype of `InitialValueProblem` and solves it. Such a solver can be used with `OrdinaryDiffEq.ODEProblem` too, so I wanted to give the user the possibility to make `OrdinaryDiffEq.ODEProblem` a subtype of `InitialValueProblem` and use the solver.

---

<div class="post-metadata">

**Author:** ![MarcMush](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcmush/32/18006_2.png) [@MarcMush](https://discourse.julialang.org/u/MarcMush)\
**Post date:** [November 2, 2020, 3:01pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/4 "2020-11-02T15:01:04Z")

</div>

you might want to use a function to check a property for example

```julia
hasthisproperty(_) = false
hasthisproperty(::ExistingStruct) = true
# or
hasthisproperty(::Type{ExistingStruct}) = true

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 3:07pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/5 "2020-11-02T15:07:17Z")

</div>

It seems to me that you have in your mind the limitation that your function/solver can only take concrete subtypes of `InitialValueProblem`. Why do not define (or just let the user define) a new method of the same function/solver which takes an `OrdinaryDiffEq.ODEProblem` instead of a subtype of `InitialValueProblem`? Functions are extensible.

Another option is the user defining a new struct which is a subtype of `InitialValueProblem` and has a `OrdinaryDiffEq.ODEProblem` inside it, and extends for this new struct any of the functions you expect to work on a `InitialValueProblem` subtype.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 3:41pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/7 "2020-11-02T15:41:13Z")

</div>

As an example of my first suggestion, you can write:

```julia
module Original
    import OrdinaryDiffEq
    function solver(x :: InitialValueProblem)
        ...
    end
    function solver(x :: OrdinaryDiffEq.ODEProblem)
        ...
    end
    export solver
end

```

Or you can leave to your user to do so:

```julia
module UserModule
    import Original, OrdinaryDiffEq
    function Original.solver(x :: OrdinaryDiffEq.ODEProblem)
        ...
    end
end

```

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 2, 2020, 3:51pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/8 "2020-11-02T15:51:49Z")

</div>

> [@Henrique\_Becker](#):
>
> It seems to me that you have in your mind the limitation that your function/solver can only take concrete subtypes of `InitialValueProblem` . Why do not define (or just let the user define) a new method of the same function/solver which takes an `OrdinaryDiffEq.ODEProblem` instead of a subtype of `InitialValueProblem` ? Functions are extensible.

The problem with this approach in my case is that the solver calls a plethora of other functions which all take `InitialValueProblem` as input.

I think the second option you’ve suggested is the best way to proceed for me.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 4:11pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/9 "2020-11-02T16:11:49Z")

</div>

My question then becomes: “why these internal functions expect a `InitialValueProblem`?” At some point, I believe, you must call methods for the specific subtype, not for the generic `InitialValueProblem` abstract supertype (otherwise the code would never interact with the instance of the concrete `struct`). Seems to me that would probably be best to drop the `:: InitialValueProblem` from the generic code and document which functions are expected to work on the parameters that had the `:: InitialValueProblem` restriction before, so any users know what to extend for their `struct` or a third-party `struct` to work with your `solver` function.

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 2, 2020, 5:10pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/10 "2020-11-02T17:10:03Z")

</div>

Indeed, this is what I had done before even asking the question, but I was hoping for `ExistingStruct <: MyAbstractType` (or any other workaround) to actually work. This is because I LOVE the inheritance structure. I do realise, however, that removing `::InitialValueProblem` might have actually been the simplest, and thus best, solution.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 5:42pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/11 "2020-11-02T17:42:01Z")

</div>

> [@giancarloantonucci](#):
>
> This is because I LOVE the inheritance structure.

I probably should follow my father’s advice that “color, taste, and love are not something you should make arguments about”, but I would like to know why you love the inheritance structure. I am on the other side of this camp, and I really would like to have some insight on the positive sides.

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 2, 2020, 6:47pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/12 "2020-11-02T18:47:36Z")

</div>

Unfortunately, my father did not give me the same advice, so I’m stuck with coding based on personal taste 😄

On a serious note, I believe that inheritance gives you the possibility to add “flavour” to your variables. For example, let’s say that you are an applied mathematician and that you have a struct called `IncompressibleNavierStokesProblem`. The name might seem quite descriptive, but it does not give you any idea of what kind of solvers apply to it, etc. Setting it to be a concrete instance of, say, `MortarBasedFiniteElementProblem` can immediately give you an intuition of how `IncompressibleNavierStokesProblem` is _actually_ treated and solved. And you can extend this argument for how many nested types you want. A similar argument applies to functions (say, a function `solver` with a method specifically working on `MortarBasedFiniteElementProblem`s). In my opinion, this helps a lot connecting theory with actual code implementation, especially if you are reading someone else’s code implementation.

But this is just what works for me.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 2, 2020, 7:41pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/13 "2020-11-02T19:41:56Z")

</div>

Inheritance does provide additional hints about how a `struct` may be classified no doubt, but in Julia and many others languages (of different reasons), a `class/struct` cannot inherit from two or more supertypes. So if someone creates a new way to solve your `IncompressibleNavierStokesProblem` but its is already a subtype of `MortarBasedFiniteElementProblem` then there is no way to use the inheritance mechanism for the new way of solving. You could go for the route of allowing for multiple inheritance, but this route has its own problems.

Consequently, my ideal goes against the the use of inheritance at all, even in Julia. Ideally I would organize my code the following way: I create a module for some _concept_ I want to be able to work with, let us say, `Numbers`, and so I export a lot of functions without no method associated (i.e., no implementation whatsoever). If I created an algorithm that works over `Numbers`, then I import that module and call functions defined on it inside my functions over parameters I do not specify the type. If I want to create a new kind of number, I import `Numbers` and create a new struct for which all methods exported by `Numbers` are defined for it. Then any new `Numbers` type work with any algorithm for `Numbers` even if both were developed in separate. Also, you can easily create, or adapt from third-party, a `struct` that is both a `String` and a `Number` or any number of concepts you want simultaneously. If someone creates a different concept of what `Number` should look like, then anybody can wrap any previous `struct` to this new concept using the old concept (or relying in the internals of the struct).

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 3, 2020, 3:27pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/14 "2020-11-03T15:27:13Z")

</div>

> [@Henrique\_Becker](#):
>
> You could go for the route of allowing for multiple inheritance, but this route has its own problems.

Why would that be counterproductive? It seems to me that, at the end of the day, multiple inheritance is almost like having no inheritance at all, except that you have the advantage of attaching additional descriptors, as I was mentioning above. I’m no CS savvy, so I simply don’t know.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 3, 2020, 3:56pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/15 "2020-11-03T15:56:28Z")

</div>

> [@giancarloantonucci](#):
>
> Why would that be counterproductive?

Well, it depends on the language. The problem often boils to the `diamond` inheritance, this is you have a class `SuperSuper`, and its has two subtypes `Super1` and `Super2`, and then for some reason, you want to create a `Child` type which inherits both `Super1` and `Super2` (it is called `diamond` because the shape of this in a diagram remebers the shape of the respective card suit). In C++, for example, the `Child` would have two copies of every field in `SuperSuper` coming from two distinct parents (or you could thing of combining the fields back, but this means `Super1` methods would interfere in the same state `Super2` methods interact). In Julia, Jeff would probably go crazy trying to decide which method signatures are more specific (what is already hard enough as now, when the type hierarchy may be represented by a tree not a DAG). I am no expert on the subject, and probably some study will reveal many other underlying problems, but the fact is that my impression from many successful languages is that they found multiple inheritance to not be worth the headache.

However, one should not confuse `Multiple Inheritance` with `Interfaces` with is a system similar to the one I proposed (but not exactly the same), in which the `Type` extends an `Interface` (as a `Type` inherits another `Type`), and is probably closer to your impression of “is almost like having no inheritance at all”.

---

<div class="post-metadata">

**Author:** ![giancarloantonucci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giancarloantonucci/32/202551_2.png) [@giancarloantonucci](https://discourse.julialang.org/u/giancarloantonucci)\
**Post date:** [November 3, 2020, 4:13pm UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/16 "2020-11-03T16:13:36Z")

</div>

Thank you for the detailed reply, as well as your overall input; I’ll make sure to dig in deeper about this topic.

---

<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, 2020, 8:53am UTC](https://discourse.julialang.org/t/can-i-impose-a-super-type-for-an-existing-struct/49460/17 "2020-11-04T08:53:51Z")

</div>

> [@giancarloantonucci](#):
>
> This is because I LOVE the inheritance structure.

Just a technical note: Julia does not have what most languages describe as [inheritance](https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)) (= aquiring slots and properties from parent) at all, just _subtyping_.

AFAIK the motivation for Julia’s type system design was a a trade-off between expressiveness and complexity. The subtyping problem as is (with `UnionAll` types, etc) is already pretty involved, but is very expressive too.

Finally, you can always use [traits](https://docs.julialang.org/en/v1/manual/methods/#Design-Patterns-with-Parametric-Methods) for problems where subtyping does not suffice, they are also much more powerful.
