# \[ANN\] DispatchDoctor.jl 🩺 – offers you a prescription for type stability

**URL:** <https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837>\
**Category:** Package Announcements\
**Created:** [May 28, 2024, 1:07pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837 "2024-05-28T13:07:16Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [May 29, 2024, 3:17pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/21 "2024-05-29T15:17:18Z")

</div>

My point was whether type instability was exclusively defined as whether the returned object was a concrete type, because if that’s the case maybe could create some issues?

In any case, now that I downloaded the package, I’m a little bit confused about the following, which could be related.

```julia
using DispatchDoctor

function foo1(x)
    y = Tuple(x)

    sum(y[1:2])
end

x = [1,2,3]
@code_warntype foo1(x) # type unstable because vararg argument

@stable function foo2(x)
    y = Tuple(x)

    sum(y[1:2])
end

x = [1,2,3]
foo2(x) # it returns the output
@code_warntype foo2(x) # red signs go away, and now it's type stable

```

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [May 29, 2024, 6:26pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/22 "2024-05-29T18:26:15Z")

</div>

> [@alfaromartino](#):
>
> `@code_warntype foo2(x) # red signs go away, and now it's type stable`

This is because the body of `foo2` has been moved out into a separate function and replaced by the type stability checking code, as explained by @MilesCranmer [above](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/18). So if the code you wrote was type stable, `@code_warntype foo2(x)` will be all blue (green?) by design. To see the inference of the function body you wrote you need to figure out the gensymmed name and run `@code_warntype` on that:

```julia-repl
julia> @code_warntype var"##foo2_closure#225"(x)
MethodInstance for var"##foo2_closure#225"(::Vector{Int64})
  from var"##foo2_closure#225"(x) @ Main REPL[8]:1
Arguments
  #self#::Core.Const(var"##foo2_closure#225")
  x::Vector{Int64}
Locals
  y::Tuple{Vararg{Int64}}
Body::Int64
1 ─ nothing
│ (y = Main.Tuple(x))
│ %3 = y::Tuple{Vararg{Int64}}
│ %4 = (1:2)::Core.Const(1:2)
│ %5 = Base.getindex(%3, %4)::Tuple{Int64, Int64}
│ %6 = Main.sum(%5)::Int64
└── return %6

```

Here you get the red `Tuple{Vararg{Int64}}` as expected. But note that the function is still type-stable, since the return type is fully inferred from the argument types. Type stability only implies that the `Body::T` line in `@code_warntype` is concrete, not that every internal variable has a concrete inferred type.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 30, 2024, 8:35am UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/23 "2024-05-30T08:35:48Z")

</div>

To add one more tip @alfaromartino — I would recommend using Cthulhu.jl for this as it lets you descend into the function body.

I guess another option is for me to leave the function body in both functions? Then inspection tools like `@code_warntype` would work. And I suppose it could improve source tracking for errors, and simplify the propagation of other macros (@matthias314 - relevant to your question too).

You would still generate the second function and call `promote_op` on it; but then just not actually use it. It would exclusively be for testing the type inference of itself.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [May 30, 2024, 10:09am UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/24 "2024-05-30T10:09:53Z")

</div>

> [@alfaromartino](#):
>
> My point was whether type instability was exclusively defined as whether the returned object was a concrete type, because if that’s the case maybe could create some issues?

To detect type-instabilities inside a function when they don’t affect the inferrability of the output, you can also use JET.jl with the macros `@test_opt` and `@report_opt`

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 30, 2024, 11:22am UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/25 "2024-05-30T11:22:47Z")

</div>

Made a PR for this here: [Move body to main function definition by MilesCranmer · Pull Request #17 · MilesCranmer/DispatchDoctor.jl · GitHub](https://github.com/MilesCranmer/DispatchDoctor.jl/pull/17)

So once that merges then `@code_warntype` will still be useful on stabilized functions.

Basically now the function body is _copied_ rather than moved. And it uses the “simulator function” just to check the inferred type, but doesn’t actually call it.

It results in more codegen but it means fewer changes to the original function.

It will also simplify propagation of other macros like `@propagate_inbounds`

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [May 30, 2024, 2:50pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/26 "2024-05-30T14:50:41Z")

</div>

Thanks for all the responses! I’m interested in using it to discipline my work. However, although not related to the package, I’m always conflicted about how we should teach and understand type stability to non-programmers, or more generally people who only use Julia for applied work (I’m one of those).

In the sense of distinguishing between only inferring a concrete type for the output (stability) or inferring a concrete type for all expressions (groundedness). While the former is the definition used, like in this package, the latter is how we usually think about our code (by “we”, I mean people using Julia for applied work exclusively, without ever creating packages).

Is there any reason why type stability is defined in terms of output? I guess checking concrete types for each expression takes you down a rabbit hole? Or that any performance issue of a stable function would only be confined to that function, without propagating?

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 30, 2024, 5:25pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/27 "2024-05-30T17:25:00Z")

</div>

Just to note, the definition of “type instability” in DispatchDoctor is just a single function:

```julia
type_instability(::Type{T}) where {T} = !Base.isconcretetype(T)
type_instability(::Type{Union{}}) = false

```

You could totally always add a method for whatever other definitions you want:

```julia
import DispatchDoctor as DD
DD.type_instability(::Type{<:AbstractArray{Any}}) = true

```

which results in

```julia
julia> DD.@stable f() = Any[1, 2, 3]
f (generic function with 1 method)

julia> f()
ERROR: TypeInstabilityError: Instability detected in `f` defined at
REPL[4]:1. Inferred to be `Vector{Any}`, which is not a concrete type.

```

* * *

> [@alfaromartino](#):
>
> Is there any reason why type stability is defined in terms of output? I guess checking concrete types for each expression takes you down a rabbit hole?

I think JET.jl and Cthulhu.jl are already great at this. I want DispatchDoctor.jl to be moreso something you can just “leave on” to alert you to any type instabilities that pop up, but be removed by the compiler if things are stable. It’s hard to add `Test.@inferred` to every possible combination of input arguments to every internal method.

I’ve also noticed there is a bit of a mental overhead from needing to manually test for type instability which leads to avoidance of doing so. But having a flag you can just turn on for your whole codebase makes it much easier.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 30, 2024, 5:33pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/28 "2024-05-30T17:33:28Z")

</div>

> [@alfaromartino](#):
>
> In the sense of distinguishing between only inferring a concrete type for the output (stability) or inferring a concrete type for all expressions (groundedness). While the former is the definition used, like in this package, the latter is how we usually think about our code (by “we”, I mean people using Julia for applied work exclusively, without ever creating packages).
> 
> Is there any reason why type stability is defined in terms of output?

One other point is that sometimes it literally doesn’t matter:

```julia
julia> function f(x)
           dx = x > 0 ? -1.0 : 1
           return x + dx
       end

```

This technically has a type instability! `dx` is a `Union{Float64,Int64}`:

But, if we just let the compiler work on it, we get `@code_llvm f(1.0)`:

```llvm
define double @julia_f_436(double %0) #0 {
top:
    %1 = fcmp ule double %0, 0.000000e+00
    %unbox.pn = select i1 %1, double 1.000000e+00, double -1.000000e+00
    %value_phi2 = fadd double %unbox.pn, %0
    ret double %value_phi2
}

```

So the compiler was smart enough to make that integer a float for us.

And thus if we use `@stable` on it, the doctor is happy:

```julia
julia> @stable function f(x)
           dx = x > 0 ? -1.0 : 1
           return x + dx
       end
f (generic function with 1 method)

julia> f(1.0)
0.0

```

whereas looking at it with `@code_warntype` would highlight a type instability.

Obviously sometimes internal type instabilities matter. But there is also a reason to not worry about them, and just treat entire functions as the “atomic unit” of instability checking.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [May 30, 2024, 6:48pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/29 "2024-05-30T18:48:02Z")

</div>

> [@alfaromartino](#):
>
> the latter is how we usually think about our code (by “we”, I mean people using Julia for applied work exclusively, without ever creating packages).

I belong to this “we” most of the time, but I disagree that this is how I think about my code, and I think DispatchDoctor makes the right choice in focusing on functions as the unit of stability. The implied meaning of `@stable foo(...) = ...` is that this method of `foo` will not trigger dynamic dispatch in its callers. Dynamic dispatch within `foo` is a separate concern, and if I’m concerned about that I’ll factor out the problematic lines from `foo` into separate functions and apply `@stable` to them as well. `@code_warntype` is a great tool for discovering these lines, so it’s great that it’s no longer broken by `@stable`.

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [May 30, 2024, 8:02pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/30 "2024-05-30T20:02:39Z")

</div>

Oh maybe my question was wrongly understood. I was literally asking why developers focus on the types of outputs exclusively, rather than all the expressions. It was just to learn, wasn’t related to the package.

My point is that developers and the official documentation emphasizes type stability for performance. But, then I can come up with the following function, which is type stable by construction but problematic.

```julia
function foo(x)
    y = sum(x[1:2])
    y::Int64
end

foo([1,2,"hello"])

```

So, I’ve always wondered what kind of (technical?) reason there is for using type stability, rather than “groundedness” in the sense of this [paper](https://arxiv.org/pdf/2109.01950).

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 30, 2024, 8:48pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/31 "2024-05-30T20:48:32Z")

</div>

> [@alfaromartino](#):
>
> So, I’ve always wondered what kind of (technical?) reason there is for using type stability, rather than “groundedness” in the sense of this [paper](https://arxiv.org/pdf/2109.01950).

To save others a ctrl-F:

 ![Screenshot 2024-05-30 at 21.27.57](https://global.discourse-cdn.com/julialang/original/3X/c/2/c2b5e408daa09ac580bfca9235134d22a1106432.png)

@alfaromartino Perhaps you are making an assumption that the definitions given in this paper are the same as used in the Julia community? As far as I can tell they are not. I haven’t heard groundedness before; most others just use “type stability” loosely to refer to either situation mentioned here.

> [@alfaromartino](#):
>
> But, then I can come up with the following function, which is type stable by construction but problematic.

Keep in mind that these analysis packages are just _tools_ that a developer can use to improve their code. They still depend on the user to use them effectively. For example as @danielwe mentioned, if using DispatchDoctor, one might want to split out potentially problematic lines into separate functions so that they would get flagged correctly. But there will of course be many scenarios where it fails to catch an inference problem in code.

As mentioned previously, both Cthulhu.jl and JET.jl are other tools in the developer’s arsenal. Those are both quite popular, and work at the level of individual variables (Cthulhu successfully flags the problem in `foo`), so I think you may be jumping to conclusions if you ask “why developers focus on the types of outputs exclusively” – I do not actually think this is the case. It is just this new package DispatchDoctor.jl that uses this approach.

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [May 30, 2024, 8:52pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/32 "2024-05-30T20:52:32Z")

</div>

Indeed, people usually want _every_ variable to be correctly inferred. However, you made a crucial observation here:

> [@alfaromartino](#):
>
> Or that any performance issue of a stable function would only be confined to that function, without propagating?

If you have a function that does weird things under the hood but returns an inferrable value, then it cannot cause too much harm. It’s the same principle underlying [function barriers](https://docs.julialang.org/en/v1/manual/performance-tips/#kernel-functions): if type-instability is unavoidable, try to limit its reach.

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [May 30, 2024, 9:22pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/33 "2024-05-30T21:22:14Z")

</div>

I agree that people in forums/packages refer to “type stability” with these two possible meanings. That’s why I was wondering if there’s any reason why the official documentation defines type stability in terms of the types of outputs exclusively.  
[https://docs.julialang.org/en/v1/manual/faq/#man-type-stability](https://docs.julialang.org/en/v1/manual/faq/#man-type-stability)  
[https://docs.julialang.org/en/v1/manual/performance-tips/#Write-“type-stable”-functions](https://docs.julialang.org/en/v1/manual/performance-tips/#Write-%22type-stable%22-functions)

As @gdalle mentions, since inferring the type of each variable is the ideal situation, maybe the official documentation should be mentioning this? although, I assume there’s a reason for Julia’s developers sticking to this definition.

I’m just going too much out of topic. The important thing is: great package!

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 31, 2024, 2:59am UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/34 "2024-05-31T02:59:00Z")

</div>

> [@alfaromartino](#):
>
> That’s why I was wondering if there’s any reason why the official documentation defines type stability in terms of the types of outputs exclusively.  
> [https://docs.julialang.org/en/v1/manual/faq/#man-type-stability](https://docs.julialang.org/en/v1/manual/faq/#man-type-stability)  
> [https://docs.julialang.org/en/v1/manual/performance-tips/#Write-“type-stable”-functions](https://docs.julialang.org/en/v1/manual/performance-tips/#Write-%22type-stable%22-functions)
> 
> As @gdalle mentions, since inferring the type of each variable is the ideal situation, maybe the official documentation should be mentioning this?

I am a bit confused since that second page you linked actually has the following subsection immediately underneath it:

> [@](#):
>
> ### Avoid changing the type of a variable
> 
> An analogous “type-stability” problem exists for variables used repeatedly within a function:
> 
> ```julia
> function foo()
> x = 1
> for i = 1:10
> x /= rand()
> end
> return x
> end
> 
> ```
> 
> Local variable `x` starts as an integer, and after one loop iteration becomes a floating-point number (the result of `/` operator). This makes it more difficult for the compiler to optimize the body of the loop. There are several possible fixes:

This is specifically about type instability in variables because the return type here is stable. Maybe you missed those parts of the docs because they don’t refer to the “groundedness” term from that paper?

> [@alfaromartino](#):
>
> The important thing is: great package!

And thanks, hope the package is useful!

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 31, 2024, 6:44pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/35 "2024-05-31T18:44:18Z")

</div>

Back to the main topic – here’s a sharp edge I found:

```julia
julia> Base.isconcretetype(Type{Float32})
false

```

Not sure what to do with this… Should it get flagged? Is `Type{Float32}` actually not a concrete type?

Edit: Is this a Julia bug? It seems like because `isconcretetype` has `@nospecialize` turned on, they aren’t actually extracting the correct type here…

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [May 31, 2024, 7:17pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/36 "2024-05-31T19:17:01Z")

</div>

Are `Type{T}`s concrete? According to [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#man-typet-type), they are abstract parametric types.

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 31, 2024, 7:25pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/37 "2024-05-31T19:25:57Z")

</div>

I am honestly not sure…

It says

> For each type `T` , `Type{T}` is an abstract parametric type whose only instance is the object `T` .

So `Type{T}` contains the object `T`. But… `Val{x}` is a type that contains the object `x` – and `Val{x}` is type stable.

So even if the relation `typeof(T) !== Type{T}` that defines `isconcretetype` is not satisfied (because `typeof` returns `DataType` rather than `Type{T}`), I feel like you wouldn’t want to actually call `Type{T}` “unstable”.

Because otherwise

```julia
f(::Type{T}) where {T} = T

```

is technically type unstable for the input `Int64`! Which doesn’t make sense to me.

I guess I’ll just add a workaround for this… Having functions return a type that is known at compile-time should certainly not be considered type-unstable, that’s a weird edge case.

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [May 31, 2024, 7:40pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/38 "2024-05-31T19:40:05Z")

</div>

Some nice discussion on this issue here [julia - How can you claim: (a) «Abstract types cannot be instantiated» and (b) «T is an instance of the abstract type Type{T}»? - Stack Overflow](https://stackoverflow.com/a/73366309).

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [May 31, 2024, 7:46pm UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/39 "2024-05-31T19:46:06Z")

</div>

Thanks!

Also I realized the issue may have just been because DispatchDoctor is using its own `specializing_typeof` rather than `typeof` so that it can get a `Type{T}` rather than `DataType`. This is so that `Base.promote_op` call uses `Type{T}` rather than `DataType` in the `argtypes...` (otherwise everything would show up as an instability).

But in doing so, I was effectively also doing `Base.isconcretetype(specializing_typeof(T))` which led to the issue.

Anyways it’s fixed on 0.4.2 now. Cheers.

---

<div class="post-metadata">

**Author:** ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)\
**Post date:** [June 1, 2024, 10:17am UTC](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837/40 "2024-06-01T10:17:23Z")

</div>

IIRC when making a closure over a type, inference is marking it as `DataType`, which loses information that could be conferred to consumers of the closure if it were marked as `Type{T}`. So it seems like this is somewhat of an edge case of type inference itself.

[Previous page](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837.md?page=1)

[Next page](https://discourse.julialang.org/t/ann-dispatchdoctor-jl-offers-you-a-prescription-for-type-stability/114837.md?page=3)
