# Is there a way to detect and automatically fix type-unstable code?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115>\
**Category:** General Usage\
**Created:** [October 20, 2021, 8:21pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115 "2021-10-20T20:21:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 20, 2021, 8:21pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115/1 "2021-10-20T20:21:28Z")

</div>

E.g. lets say you do:

```julia
julia> if x % 2 == 0
         x/2
       else
         2x
       end

```

I believe there is a macro to check, I forget which, but could a macro “conform” the type of both code paths, i.e. here to Float64 (as it’s an (almost) superset)? I think a macro could do it, I’m not sure, as I’m not good with writing macros yet. That would be a step in the right direction, and even better if the compiler could do it automatically for you.

A first step might be to just give you a Union of both types, whatever they are.

That’s just an example, I just used one with a Float64, as more likely do happen in practice (and I know of div, another solution). I’m just thinking this could be a bit problematic for my solution here (there only involving integers):

> [@Potential solution to the overflow problem; 64-bit considered harmful, 32- or 21-bit better](https://discourse.julialang.org/t/potential-solution-to-the-overflow-problem-64-bit-considered-harmful-32-or-21-bit-better/69918/7):
>
> Functions are not a problem, but loops are… I’m explain under B. a partial or full solution. And you don’t need to know or calculate the bound yourself, Julia gives you the types, you would only need maybe a debug mode to see them or a linter (the overflow/safety problem turns into an optimization problem compilers or linters can be good at, i.e. avoid or alerting you when your code goes to a problematically larger/slower type or BigInt). A. There are only 4 elementary integer operations to c…

Note, there I think I resolved all the issues, at least outlined the loop problem in the end. There are no showstoppers there, including this type-instability problem (while annoying and potentially slowing down, not a safety problem).

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [October 20, 2021, 8:52pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115/2 "2021-10-20T20:52:20Z")

</div>

The macro to check is `@code_warntype`.

```julia
julia> function f(x)
       if x % 2 == 0
                x/2
              else
                2x
              end
       end
f (generic function with 1 method)

julia> @code_warntype f(4)
Variables
  #self#::Core.Const(f)
  x::Int64

Body::Union{Float64, Int64}
1 ─ %1 = (x % 2)::Int64
│ %2 = (%1 == 0)::Bool
└── goto #3 if not %2
2 ─ %4 = (x / 2)::Float64
└── return %4
3 ─ %6 = (2 * x)::Int64
└── return %6

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 20, 2021, 8:56pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115/3 "2021-10-20T20:56:05Z")

</div>

> [@Palli](#):
>
> a macro “conform” the type of both code paths, i.e. here to Float64

no, Numba does this, but it distorts the user intention so I don’t think it’s a good thing

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 21, 2021, 4:37pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115/4 "2021-10-21T16:37:14Z")

</div>

You mean Numba does this automatically (without a macro since Python doesn’t have macros), not that a macro in Julia couldn’t be implemented, only that you don’t want it?

But note it would make the intention explicit (I know there are other ways for that, I’m thinking of better ways), and as is, it’s not at all clear what the user wanted, regarding types, can’t be read from the code as it is (or the programmer actually intended for type-stable AND type-unstable). It could be:

```julia
julia> @code_warntype f(1.0)
[..]
Body::Float64

```

what the programmer had in mind, i.e. always called with Float64 and that IS type-stable. But while the code IS general, it’s not type-stable in general. It is type-unstable as I stated, and shown earlier, or in a different way, if the programmer thinks he’s fixing it this way:

```julia
julia> function f(x)
         if x % 2 == 0
           x/2
         else
           2.0x
         end
       end

```

then instead type-unstable for e.g. Float32 input (also Float16, while not for Float64 and all integers):

```julia
@code_warntype f(2.0f0)
[..]
Body::Union{Float32, Float64}

```

and:

```julia
julia> @code_warntype f(Rational(2))
MethodInstance for f(::Rational{Int64})
  from f(x) in Main at REPL[63]:1
Arguments
  #self#::Core.Const(f)
  x::Rational{Int64}
Body::Union{Rational{Int64}, Float64}
1 ─ %1 = (x % 2)::Rational{Int64}
│ %2 = (%1 == 0)::Bool
└── goto #3 if not %2
2 ─ %4 = (x / 2)::Rational{Int64}
└── return %4
3 ─ %6 = (2.0 * x)::Float64
└── return %6

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 21, 2021, 4:44pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-detect-and-automatically-fix-type-unstable-code/70115/5 "2021-10-21T16:44:24Z")

</div>

```julia
In [5]: @numba.njit
   ...: def f(x):
   ...: if x>1:
   ...: return 1
   ...: else:
   ...: return 1.0
   ...: 

In [6]: f(2)
Out[6]: 1.0

In [7]: f(0.1)
Out[7]: 1.0

```

I mean you can already do this by:

```julia
julia> function f(x)::Float64
       if x % 2 == 0
                x/2
              else
                2x
              end
       end

```
