# Inheritance and Dispatch with Restricted Type Parameters of Abstract Super Type

**URL:** <https://discourse.julialang.org/t/inheritance-and-dispatch-with-restricted-type-parameters-of-abstract-super-type/68444>\
**Category:** General Usage\
**Created:** [September 20, 2021, 8:20am UTC](https://discourse.julialang.org/t/inheritance-and-dispatch-with-restricted-type-parameters-of-abstract-super-type/68444 "2021-09-20T08:20:52Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![manuelbb-upb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/manuelbb-upb/32/25222_2.png) [@manuelbb-upb](https://discourse.julialang.org/u/manuelbb-upb)\
**Post date:** [September 20, 2021, 8:20am UTC](https://discourse.julialang.org/t/inheritance-and-dispatch-with-restricted-type-parameters-of-abstract-super-type/68444/1 "2021-09-20T08:20:52Z")

</div>

Hi,

I was confused by the dispatch behavior with a hierarchy of types with (restricted) type parameters. Now I want to know if I understand correctly why the following does not work as I initially expected:

## 1st Example

Suppose, I have a type hierarchy

```julia
abstract type SuperRestricted{A<:Real} end
struct SubFree{A} <: SuperRestricted{A} end

```

In the definition of `SubFree` i did not restrict `A` out of laziness first. And as expected, something as `SubFree{Complex}` will result in a `TypeError`.  
Next I wanted a method to dispatch for every subtype of `SuperRestricted`:

```julia
func = ( x :: Type{<:SuperRestricted} ) -> println("Success.")

```

It works for `func(SuperRestricted)` but not for `func(SubFree)` because – to my surprise – `SubFree <: SuperRestricted` is `false`.

However, for

```julia
struct SubRestricted{A<:Real} <: SuperRestricted{A} end

```

we have `SubRestricted <: SuperRestricted` and `func(SubRestricted)` works.

## 2nd Example

Upon further experimentation I found that

```julia
abstract type SuperFree{A} end
struct SubFree{A} <: SuperFree{A} end
struct SubRestricted{A <: Real} <: SuperFree{A} end

SubFree <: SuperFree # true
SubRestricted <: SuperFree # true

```

## Suspected Explanation(?)

In the first example, `SuperRestricted{A<:Real}` describes a **set of types** where `A` must be real.  
Just from the definition of `SubFree{A}` it seems that for this subtype `A` might be anything and hence the set of types described by `SubFree` are not a subset of the types `SuperRestricted` in the mathematical sense. In constracst, `SubRestricted{A<:Real}` is really a subset of types.  
Likewise, in the second example, `SuperFree{A}` does not put any bounds on `A` and that is why subtypes can restrict it or not and truly remain subtypes.

Is that roughly correct?

In retrospect (and with these descriptive type names) it seems logical. I was confused first, because I thought that inheriting from a restricted type would make the subtype automatically restricted as well and the TypeError from `SubFree{Complex}` in the first example somewhat confirmed me in this assumption.
