# Changing struct fields to a different sub-type during run time

**URL:** https://discourse.julialang.org/t/changing-struct-fields-to-a-different-sub-type-during-run-time/132346
**Category:** Modelling & Simulations
**Tags:** question, performance, type, aerospace
**Created:** [September 13, 2025, 12:56pm UTC](https://discourse.julialang.org/t/changing-struct-fields-to-a-different-sub-type-during-run-time/132346 "2025-09-13T12:56:01Z")
**Posts on this page:** 1
**Showing post:** 8

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [September 14, 2025, 1:35pm UTC](https://discourse.julialang.org/t/changing-struct-fields-to-a-different-sub-type-during-run-time/132346/8 "2025-09-14T13:35:45Z")

</div>

> [@sgaure](#):
>
> However, dispatch on variants of `TimeType` is problematic.

That’s what I remembered from another thread. But now that I’m actually trying the package and looking into the source code, it’s type-stable and scales up _if_ every type has `seconds::Float64`. For a more modest example that exceeds the automatic Union-splitting optimization of 3, `getproperty` does something like this:

```julia-auto
        v = (LightSumTypes).unwrap(sumt)
        if v isa T1
            return (Base).getproperty(v, s)
        elseif v isa T2
            return (Base).getproperty(v, s)
        elseif v isa T3
            return (Base).getproperty(v, s)
        elseif v isa T4
            return (Base).getproperty(v, s)
        elseif v isa T5
            return (Base).getproperty(v, s)
        else
            error("THIS_SHOULD_BE_UNREACHABLE")
        end

```

So while a normal `getproperty` call or equivalent `structure.property` expression for a type-unstable `structure::Union{...}` would fail, the concrete `LightSumType` would branch to every specified type and _separately_ call `getproperty` again. If all those inner `getproperty`s have the same concrete return type, then the overall `getproperty` shares the type; if they don’t, then it takes very little variation to lose type stability. Pretty much every fundamental function generated by `@sumtype` has this branch, and it doesn’t have the extra help of assertions or conversions. The successor (in the sense that both are authored by Tortar) `WrappedUnions.@unionsplit` puts that branch generation in the user’s hands, which I am guessing would also let the user add `convert` calls to restore type stability. To manually write the branch’s expressions instead of generating duplicates, you’d need an API like `@cases` of SumTypes.jl; I mention this because I expect the various time types to typically have different operations, not just `Float64` arithmetic.

`f` surprised me a bit. `variant` evidently does not reach a stable return type via some large branch; that branch can’t happen at that stage anyway. However, the compiler was still able to spot the 50 `f` methods for the 50 `T#=i=#` types all reached `seconds::Float64`; to my knowledge, that far exceeds the default Union-splitting optimization (3) and inference of multiple applicable methods (4). I don’t understand the compiler much, maybe someone else can comment. EDIT: The limit was removed for linear signatures, whatever that means [RFC: inference: remove union-split limit for linear signatures by vtjnash · Pull Request #37378 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/37378)

A big set of types has other limits however. The `Union`-annotated field of these approaches _are_ internally implemented like C’s tagged unions if all the types are `isbits`, but that only goes up to 256 types because the tag is 1 byte. Even if that limit is increased, the parser currently hits a recursion limit for `if`-`elseif` branches somewhere [between 256 and 65536](https://discourse.julialang.org/t/need-help-implementing-evenness-test-for-larger-integer-types/127607).

---

_[View the full topic](https://discourse.julialang.org/t/changing-struct-fields-to-a-different-sub-type-during-run-time/132346)._
