# Type stability in hierarchichal function calls

**URL:** <https://discourse.julialang.org/t/type-stability-in-hierarchichal-function-calls/130603>\
**Category:** Performance\
**Tags:** type-stability\
**Created:** [July 10, 2025, 10:36am UTC](https://discourse.julialang.org/t/type-stability-in-hierarchichal-function-calls/130603 "2025-07-10T10:36:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![thomasc791](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thomasc791/32/214650_2.png) [@thomasc791](https://discourse.julialang.org/u/thomasc791)\
**Post date:** [July 10, 2025, 10:36am UTC](https://discourse.julialang.org/t/type-stability-in-hierarchichal-function-calls/130603/1 "2025-07-10T10:36:57Z")

</div>

Hi all,

I have a question on how type stability traverses into layers of function calls. Meaning, if I have a function `assembly` that is not completely type stable, because it contains a `Vector{Types}`. In `assembly` I call another function `_local_assembly`, which is type stable. When I call `@code_warntype` I can only see one layer deep, so I can check the type stabilities independently, but not see if `_local_assembly` is actually type stable in the `assembly` call.

```julia
function _local_assembly(::Type{T}) where {T}
  ... # do something computationally intensive
end

function assembly(a::Vector{Types})
  for t in eachindex(a)
    _local_assembly(a[t])
  end
end

```

In this case local assembly can specialise per type, but assembly is type-unstable. Let’s say that the heavy lifting is done in `_local_assembly`, and `assembly` just dispatches the computation per type. Can I assume that the `_local_assembly` function is actually type stable, and performant, or does the type-instability “follow” the function calls?

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [July 10, 2025, 12:24pm UTC](https://discourse.julialang.org/t/type-stability-in-hierarchichal-function-calls/130603/2 "2025-07-10T12:24:43Z")

</div>

Regarding the underlying question about debugging such things: Cthulhu.jl provides the `@descend` macro which provides similar infos as `@code_warntype` and much more, plus it allows you to interactively “descend” deeper into nested function calls and inspect what goes on at each level.

In general, the pattern you have above looks like a “function barrier”, i.e. the inner function `_local_assembly` will be called with each particular element of the `Vector{Type}` and, as you said, a specialized method will be compiled for each case (inside the inner function, the object then has a known type and there is no type instability).

There will still be “dynamic dispatch” in general since inside `assembly` the runtime has to figure out which method of `_local_assembly` to call, but if the operation within `_local_assembly` takes much longer than the outer loop over the `Vector{Type}`, there should be no big impact in the end. Only when you have a “hot loop”, i.e. you run over a large abstract collection (like `Vector{Type}`) and do many small operations (i.e. `a` is very long and `_local_assembly` is fast), you will notice the large overhead of dynamic/runtime dispatch.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [July 10, 2025, 2:39pm UTC](https://discourse.julialang.org/t/type-stability-in-hierarchichal-function-calls/130603/3 "2025-07-10T14:39:51Z")

</div>

The previous poster described function barriers well. But just in case, the manual section on function barriers is [here](https://docs.julialang.org/en/v1/manual/performance-tips/#kernel-functions).
