# Why is it impossible to subtype a struct?

**URL:** <https://discourse.julialang.org/t/why-is-it-impossible-to-subtype-a-struct/19876>\
**Category:** General Usage\
**Created:** [January 21, 2019, 2:56pm UTC](https://discourse.julialang.org/t/why-is-it-impossible-to-subtype-a-struct/19876 "2019-01-21T14:56:38Z")\
**Posts on this page:** 1\
**Showing post:** 9

<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 22, 2019, 12:32am UTC](https://discourse.julialang.org/t/why-is-it-impossible-to-subtype-a-struct/19876/9 "2019-01-22T00:32:11Z")

</div>

> [@StefanKarpinski](#):
>
> A type can only be instantiated if it is _completely_ specified, and it only makes sense to subtype something if it is _incompletely_ specified. Thus, a type should either be abstract or concrete but not both.

I think there is some tension between the above statement, which is both logical and desirable for performance reasons, and the actual possibility to reuse code.

In practice, it can happens that a type is completely specified for someone, but incompletely specified for someone else. The important word here is _incompletely_: it means that what is available is already a good starting point, but something else is missing.

While this is not a big issue for structure definitions (we can always use macros to copy/paste fields), it is a huge problem for code reuse since:

- abstract types carry no information on the actual data representation;
- methods operate on specific data representations, hence their arguments will be annotated with concrete types;
- but concrete types can not be subtyped, hence those method implementations are locked, and can not be reused.

This problem might be mitigated if we could attach a specific data representation to abstract types. Besides, there are cases where an abstract type will always have one (and only one!!) concrete subtype (consider the `DataFrame` case, thoroughly discussed [here](https://discourse.julialang.org/t/how-to-add-metadata-info-to-a-dataframe/11168): in this case the distinction between `AbstractDataFrame` and `DataFrame` is almost fictitious, and they are actually the same thing).

> [@StefanKarpinski](#):
>
> You end up with attempts to resolve this confusion like the “final” keyword and recommendations against ever subtyping classes that weren’t intended to be abstract. But wouldn’t it be better not to conflate the two things in the first place?

I completely agree that allowing subtyping in all cases brings more damage than advantages, but disallowing it in all cases prevents code reuse (as discussed above). It looks like we need a comporomise in the allowing/disallowing concrete subtyping and abstract/concrete dichotomy…

In [ReusePatterns](https://github.com/gcalderone/ReusePatterns.jl) I explore the possibility to exploit one such compromise through the concept of _quasi-abstract_ type, i.e. a type which:

- can be subtyped like an abstract one;
- can have data representation attached, like a concrete one;
- introduce a performance penalty if used in a container, like an abstract one;
- can be used to annotate method arguments, with no performance penalty, like a concrete one.
- it inherits the structure fields of its ancestors, unlike both abstract and concrete types.
- it is **supposed** to be subtyped, i.e. the author clearly states that it is not `final` and (most importantly) it fosters code reuse.

> [@StefanKarpinski](#):
>
> n other words, the above abstract type declaration would have no effect except acting as documentation that `Rectangle{T}` is _supposed_ to have `width` and `height` properties that return values of type `T` . That just doesn’t seem like a sufficiently compelling feature to add it until it has some more useful meanin

I agree there is no value added in the structure definition, but there is a huge advantage for code reuse: e.g. `function mymethod(input::Rectangle)` could be reused by all `Rectangle` subtypes, since they will all contain the `width` and `height` fields.

In summary: we may safely neglect the problem of concrete subtyping (there are macro for this), but for the purpose of code reuse it might be useful to attach data representation to an abstract type (making it a _not-so-abstract_ one, or _quasi-abstract_). Incidentally, the latter condition brings the possibility of concrete subtyping, even if it was not the original goal.

As R.P. Feynman once said: _sure it can give some practical results, but that’s not why we do it!_. 😉

---

_[View the full topic](https://discourse.julialang.org/t/why-is-it-impossible-to-subtype-a-struct/19876)._
