# Why are self-referential struct parameters impossible?

**URL:** <https://discourse.julialang.org/t/why-are-self-referential-struct-parameters-impossible/110982>\
**Category:** Internals & Design\
**Tags:** type, parametric-types, recursion, parameters\
**Created:** [February 29, 2024, 11:18pm UTC](https://discourse.julialang.org/t/why-are-self-referential-struct-parameters-impossible/110982 "2024-02-29T23:18:12Z")\
**Posts on this page:** 1\
**Showing post:** 13

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 1, 2024, 4:51pm UTC](https://discourse.julialang.org/t/why-are-self-referential-struct-parameters-impossible/110982/13 "2024-03-01T16:51:41Z")

</div>

No, my tone is just “I’m not gonna write a whole essay here.” I figured a quick response would be more useful than nothing at all. Brevity is a virtue, both for the writer and the reader.

So fundamentally, the constraint is what @Benny already mentioned and linked to above — that we don’t have forward declarations for types. But because you’re dealing with _subtyping_ within the parameters, you just need to have an abstract type to reference. This works (but only for perfectly balanced trees):

```Julia
julia> abstract type AbstractTree; end;

julia> struct Tree{V,T<:Union{AbstractTree,Nothing}} <: AbstractTree
           value::V
           left::T
           right::T
       end

julia> Tree(1, Tree(2, nothing, nothing), Tree(3, nothing, nothing))
Tree{Int64, Tree{Int64, Nothing}}(1, Tree{Int64, Nothing}(2, nothing, nothing), Tree{Int64, Nothing}(3, nothing, nothing))

```

You can fix that, of course, either by using two different parameters for the two leafs or with a custom constructor as you’ve already discovered. The default constructors try to get a concrete type because that’s generally what you want and is best for performance.

But note that the structure of the tree is reflected _both_ in its type and in its data. We’re not talking about trouble with recursive _data_, but rather you’re seeking to put the exact structure of that information into the type domain. And that’s where you need to consider the [tradeoffs on values vs. types](https://discourse.julialang.org/t/overhead-of-dynamic-dispatch/7089/5).

---

_[View the full topic](https://discourse.julialang.org/t/why-are-self-referential-struct-parameters-impossible/110982)._
