# Automatically generate default instances for all concrete subtypes of a type

**URL:** <https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212>\
**Category:** New to Julia\
**Tags:** type\
**Created:** [May 21, 2025, 11:46am UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212 "2025-05-21T11:46:17Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 21, 2025, 11:46am UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/1 "2025-05-21T11:46:17Z")

</div>

TL; DR: for a given abstract type, generate a vector/tuple/whatever containing a default instance for each of its concrete subtypes.

un-XY: I have several concrete types that subtype an abstract supertype (possibly indirectly), and each of these concrete types defines two methods, for which I would like to check that they agree (let’s say in the “default” case). As such, I would like to

- iterate over all concrete types that subtype my abstract type
- register a `get_default()` function for each of these concrete types that gives me a default instance, `def`, for the given concrete type
- for `def`, run some routine to verify that the methods are consistent
- as soon as an inconsistency is detected, error

To illustrate in a MWE (that won’t run because I don’t know how to define a few components…)

```julia
using Random
Random.seed!(42)
abstract type Abs_type end
abstract type Abs_sub1 <: Abs_type end
struct A <: Abs_type end
struct B <: Abs_sub_1 end
struct C <: Abs_sub_1 end

# Method 1 and method 2 should be such that method1(x, ::Abs_type) + method2(x, ::Abs_type) == 0
## Consistent definition for A
method1(x, ::A) = x
method2(x, ::A) = -x
## Consistent definition for B
method1(x, ::B) = -x
method2(x, ::B) = x
## Inconsistent definition for C
method1(x, ::C) = x
method2(x, ::C) = 0 * x

function test(N)
    concrete_subtypes = get_concrete_subtypes(Abs_type) # How to get these? 
    x = rand(N)
    for s in concrete_subtypes
        s_def = get_default(s) # How to get these? I know I'll have to define get_default for each concrete subtype, but how do I dispatch on these?
        @assert all(method1(xi, s) + method2(xi, s) ≈ 0 for xi in x) 
    end
    return nothing
end

```

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 21, 2025, 12:03pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/2 "2025-05-21T12:03:23Z")

</div>

(I won’t be using this in any performant calculation, it will instead serve as automated checks that all methods remain consistent if I’ve been tinkering around with some of them)

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 21, 2025, 12:11pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/3 "2025-05-21T12:11:47Z")

</div>

> [@JADekker](#):
>
> `concrete_subtypes = get_concrete_subtypes(Abs_type) # How to get these?`

```julia-repl
julia> using AbstractTrees
 
julia> struct TypeTree
           type::Type
       end
 
julia> function AbstractTrees.children(tree::TypeTree)
           Iterators.map(TypeTree, subtypes(tree.type))
       end
 
julia> abstract type A end
 
julia> struct P <: A end # finitely-many subtypes
 
julia> struct Q <: A end # finitely-many subtypes
 
julia> struct R{X} <: A end # infinitely-many subtypes!
 
julia> leaf_subtypes = Iterators.map((x -> x.type), Leaves(TypeTree(A)));
 
julia> concrete_leaves = Iterators.filter(isconcretetype, leaf_subtypes);
 
julia> collect(Type, leaf_subtypes)
3-element Vector{Type}:
 P
 Q
 R
 
julia> collect(Type, concrete_leaves)
2-element Vector{Type}:
 P
 Q

```

> [@JADekker](#):
>
> `s_def = get_default(s) # How to get these? I know I'll have to define get_default for each concrete subtype, but how do I dispatch on these?`

Not sure what you mean.

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 21, 2025, 12:16pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/4 "2025-05-21T12:16:27Z")

</div>

Thank you, that solves the first part!

For `s_def = get_default(s)`, what I mean is that I could define:

```julia
get_default(::A) = A()
get_default(::B) = B()
etc.

```

(which is a bit silly as my example didn’t include fields). However, the values in your `leaf_subtypes` are of type `Type`, so I can’t dispatch on them, right?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 21, 2025, 12:17pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/5 "2025-05-21T12:17:29Z")

</div>

```julia
get_default(::Type{A}) = A()
get_default(::Type{B}) = B()

```

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [May 21, 2025, 12:19pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/6 "2025-05-21T12:19:29Z")

</div>

Thanks, that all works like a charm!

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 21, 2025, 12:21pm UTC](https://discourse.julialang.org/t/automatically-generate-default-instances-for-all-concrete-subtypes-of-a-type/129212/7 "2025-05-21T12:21:29Z")

</div>

> [@nsajko](#):
>
> `Iterators.map(TypeTree, subtypes(tree.type))`

One thing to keep in mind is:

```julia-repl
julia> @which subtypes
InteractiveUtils

```

So, if you’re doing this in a non-interactive context, like a script or a test suite, you’ll need to import `InteractiveUtils`, for example like `using InteractiveUtils: subtypes`.
