# \`code\_warntype\` understanding

**URL:** <https://discourse.julialang.org/t/code-warntype-understanding/48627>\
**Category:** New to Julia\
**Tags:** performance, type, numerics\
**Created:** [October 19, 2020, 1:50pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627 "2020-10-19T13:50:55Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 19, 2020, 1:50pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/1 "2020-10-19T13:50:55Z")

</div>

Here is a code that puzzles me. How can it be?

```julia
@code_warntype model(2.1,0.3,0.3; pars=[1,1,1.0]) # fine, body::Complex{Float64}
#
x(a,b,c) = model(a,b,c; pars=[1,1,1.0])
@code_warntype x(2.1,0.3,0.3) # body::Any

```

In general, should I care? the function `x` is passed to `Cuba.curhe` for multidimensional integration.  
Do you think I should try to fix this `::Any`?

Thanks

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 19, 2020, 2:00pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/2 "2020-10-19T14:00:15Z")

</div>

I’m very confused with the type inference.

Here is another example

```julia
const testLM = [(L=1, M=1), (L=3,M=1)]
const testA = rand(Complex{Float64},2)
#
@code_warntype Psi(3,1,0.3,0.3) # ::Float64
recamp(cosθ,ϕ,amps,LMs) = sum(a*Psi(L,M,cosθ,ϕ) for (a, (L, M)) in zip(amps,LMs))
@code_warntype recamp(0.3,0.3,testA,testLM) # ::Any

```

but

```julia
function test()
    return recamp(0.3,0.3,testA,testLM)
end
@code_warntype test() # Body::Float64

```

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 19, 2020, 2:09pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/3 "2020-10-19T14:09:32Z")

</div>

For some reason, the original case behaviors differently

```julia
function test()
    return x(2.1,0.3,0.3)
end
@code_warntype test() # Body::Any

```

😕

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 19, 2020, 2:58pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/4 "2020-10-19T14:58:09Z")

</div>

What is `Psi` or `model`. What is the output of `@code_warntype`. It’s impossible to tell without more complete information. (edit: and as a guess `model`, `Psi` and `x` may not be constant)

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 19, 2020, 7:13pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/5 "2020-10-19T19:13:40Z")

</div>

Sure, it needs some effort to isolate all model calls in a simple code to be posted.  
Could you tell me please if it looks to you as awkward, weird and counterintuitive as it does for me?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 19, 2020, 8:34pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/6 "2020-10-19T20:34:11Z")

</div>

One way this can show up is via constant propagation. Here is a silly function which is obviously type-unstable:

```julia
julia> function f(x)
         if x < 1
           return "hello"
         else
           return 1.0
         end
       end
f (generic function with 1 method)

julia> @code_warntype f(1)
Variables
  #self#::Core.Compiler.Const(f, false)
  x::Int64

Body::Union{Float64, String}

```

However, if we wrap this in another function and fix its argument, then something interesting happens:

```julia
julia> function g()
         x = 2
         f(x)
       end
g (generic function with 1 method)

julia> @code_warntype g()
Variables
  #self#::Core.Compiler.Const(g, false)
  x::Int64

Body::Float64
1 ─ (x = 2)
│ %2 = Main.f(x::Core.Compiler.Const(2, false))::Core.Compiler.Const(1.0, false)
└── return %2

```

When compiling `g()`, the compiler is able to prove that `x = 2` and therefore only the `else` clause in `f(x)` will occur, so it knows that `g()` returns a `Float64`. In fact, it even knows that `g()` returns 1.0 (note the `Const(1.0, ...)`).

`@code_warntype f(1)` doesn’t show you this because `@code_warntype` _actually_ only uses the _types_ of the input provided:

```julia
julia> @macroexpand @code_warntype f(1)
:(InteractiveUtils.code_warntype(f, (Base.typesof)(1)))

```

Note that `typeof(1)` which is simply `Int`. That means that `@code_warntype` can’t show you the results of constant propagation in the expression you provide it.

However, in the case of `@code_warntype g()`, the constant `x = 2` is already baked into the definition of `g()`, so the result of that constant propagation can be shown.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 19, 2020, 10:49pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/7 "2020-10-19T22:49:38Z")

</div>

> [@misha\_mikhasenko](#):
>
> Could you tell me please if it looks to you as awkward, weird and counterintuitive as it does for me?

No. This can definately happen especially if my guess is true.

> [@rdeits](#):
>
> One way this can show up is via constant propagation. Here is a silly function which is obviously type-unstable:

No that doesn’t matter at all.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [October 19, 2020, 11:07pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/8 "2020-10-19T23:07:29Z")

</div>

> `model` , `Psi` and `x` may not be constant

Minimal example reproducing OP’s problem:

```julia
julia> struct Model
           x::Float64
       end

julia> (m::Model)(y) = m.x * y

julia> model = Model(3.5) # model is a non-constant global
Model(3.5)

julia> @code_warntype model(2)
Variables
  m::Model
  y::Int64

Body::Float64
1 ─ %1 = Base.getproperty(m, :x)::Float64
│ %2 = (%1 * y)::Float64
└── return %2

julia> modelcall() = model(2) # using non-constant global "model" within a function definition
modelcall (generic function with 1 method)

julia> @code_warntype modelcall()
Variables
  #self#::Core.Const(modelcall)

Body::Any
1 ─ %1 = Main.model(2)::Any
└── return %1

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 19, 2020, 11:07pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/9 "2020-10-19T23:07:37Z")

</div>

Well, that was rude and unhelpful.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 19, 2020, 11:43pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/10 "2020-10-19T23:43:15Z")

</div>

> [@Elrod](#):
>
> ```julia
> julia> model = Model(3.5) # model is a non-constant global
> 
> ```

~~Yes this is the cause as I said.~~  
I thought that was from OP.  
I guess it’s still uncertain if this is the actual cause.

> [@rdeits](#):
>
> Well, that was rude and unhelpful.

Errr, well, but it is simply true that constant propagation doesn’t matter at all here. Please read the original post more carefully to see how the comparison you made was the wrong way around. It should not be unhelpful since I was hoping that the difference is relatively easy to see.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [October 19, 2020, 11:58pm UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/11 "2020-10-19T23:58:09Z")

</div>

> [@yuyichao](#):
>
> ~~Yes this is the cause as I said.~~  
> I thought that was from OP.  
> I guess it’s still uncertain if this is the actual cause.

Yes. The OP hadn’t posted a minimal example yet, so I commented with an example illustrating the issue. I think new users can miss the fact that just because something looks like a function, doesn’t mean it is a constant.

A simpler example would have been

```julia
model = x -> 3x
@code_warntype model(6)
modelcall() = model(7)
@code_warntype modelcall()

```

but I figured @misha_mikhasenko’s example may look more similar to the struct definition with an added call method, and seeing the example would help confirm/deny that this is what is going on.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 20, 2020, 12:39am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/12 "2020-10-20T00:39:52Z")

</div>

> [@Elrod](#):
>
> may look more similar to the struct definition with an added call method

FWIW, I have real code for data fitting more similar to

```julia
gen_model(p0) = (x, p) -> f(x, p, p0)

```

and I either assign the result to a `const`, or use the result inline, or simply in most cases don’t really care about the top level dispatch = = …

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 20, 2020, 8:43am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/13 "2020-10-20T08:43:04Z")

</div>

> [@yuyichao](#):
>
> It should not be unhelpful since I was hoping that the difference is relatively easy to see.

Offtopic, but maybe important: @rdeits is probably seeing it quite easily, but I do not so easily and OP maybe neither. And even after a while I think I found out, but I am still unsure, if I am not thinking wrong. So, I don’t know who you want to address, but for me your hopes aren’t fulfilled 😉

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 8:53am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/14 "2020-10-20T08:53:14Z")

</div>

thanks to everyone who commented.

Here is the first case, where `::Any` desapper once you put the call to the function

```julia
module MyTest
    using PartialWaveFunctions
    Psi(L,M,cosθ,ϕ) = sqrt((2L+1)/(2π))*wignerd(L,M,0,cosθ)*sin(M*ϕ)
    recamp(cosθ,ϕ,amps,LMs) = sum(a*Psi(L,M,cosθ,ϕ) for (a, (L, M)) in zip(amps,LMs))
    export recamp, Psi
end
# 
using .MyTest

const testLM = [(L=1, M=1), (L=3,M=1)]
const testA = rand(Complex{Float64},2)
#
@code_warntype Psi(3,1,0.3,0.3) # ::Float64
recamp(0.3,0.3,testA,testLM)
@code_warntype recamp(0.3,0.3,testA,testLM) # ::Any
#
function test()
    return recamp(0.3,0.3,testA,testLM)
end
@code_warntype test() # Body::Float64

```

`PartialWaveFunctions` is my package (registered), so it might have something to do with it.  
If I replace `PartialWaveFunctions.wignerd(L,M,0,cosθ)` with `SpecialFunctions.gamma(L*cosθ)` (just for a check), the problem with `::Any` does not show up.

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 9:12am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/15 "2020-10-20T09:12:17Z")

</div>

Here is the second example,

```julia

module MyTest2
    using Parameters
    function build_model(list_of_settings)
        function model(x; pars)
            return sum(p*modelA(x; settings=s)
                for (p,s) in zip(pars, list_of_settings))
        end
        return model
    end
    function modelA(x; settings)
        @unpack N, k, p = settings
        value = sum((k*x)^i*cis(i*p*x) for i in 1:N)
        return value
    end

    export build_model
end

using .MyTest2

const list_of_settings = [(N=3,k=0.1,p=0.3),
                    (N=5,k=0.5,p=0.3),
                    (N=7,k=0.2,p=0.3)]
# 
model = build_model(list_of_settings)
# 
model(2.2; pars=[1,1,1.0])
@code_warntype model(2.2; settings=[1,1,1.0]) # fine, body::Complex{Float64}
#
M(x) = model(x; pars=[1,1,1.0])
@code_warntype M(2.2) # body::Any

function test()
    return M(2.2)
end
@code_warntype test() # Body::Any

```

Here wrapping to a test function does not help.

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 9:17am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/16 "2020-10-20T09:17:33Z")

</div>

Indeed, the code from @Elrod would be the simplest example of the same behavior

```julia
model = x -> 3x
@code_warntype model(6) # Body::Int64
modelcall() = model(7)
@code_warntype modelcall() # Body::Any
#
function test()
    modelcall()
end
@code_warntype test() # Body::Any

```

My question is should I care about this `Any` in performance optimization? Or it is just `@code_warntype` fooling me and internally everything is working as efficient as possibly be?

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 9:25am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/17 "2020-10-20T09:25:05Z")

</div>

> [@rdeits](#):
>
> `@code_warntype f(1)` doesn’t show you this because `@code_warntype` _actually_ only uses the _types_ of the input provided:
> 
> ```julia
> julia> @macroexpand @code_warntype f(1)
> :(InteractiveUtils.code_warntype(f, (Base.typesof)(1)))
> 
> ```

that is very helpful to know, thanks.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 20, 2020, 9:41am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/18 "2020-10-20T09:41:08Z")

</div>

No, `@code_warntype` is correct here, because `model` is a non-constant global. You should either declare it as a constant using the `const` keyword or make it an argument to `modelcall`.

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 9:41am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/19 "2020-10-20T09:41:23Z")

</div>

> [@misha\_mikhasenko](#):
>
> Indeed, the code from @Elrod would be the simplest example of the same behavior

Hm, not sure anymore that it is true. For Elrod’s example  
setting model to const would cure the problem `const model = x -> 3x`.  
For my case it does not help.

---

<div class="post-metadata">

**Author:** ![misha\_mikhasenko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/misha_mikhasenko/32/5060_2.png) [@misha\_mikhasenko](https://discourse.julialang.org/u/misha_mikhasenko)\
**Post date:** [October 20, 2020, 9:43am UTC](https://discourse.julialang.org/t/code-warntype-understanding/48627/20 "2020-10-20T09:43:42Z")

</div>

Fixed `const model = build_model(list_of_settings)` in the MWE above

```julia
module MyTest2
    using Parameters
    function build_model(list_of_settings)
        function model(x; pars)
            return sum(p*modelA(x; settings=s)
                for (p,s) in zip(pars, list_of_settings))
        end
        return model
    end
    function modelA(x; settings)
        @unpack N, k, p = settings
        value = sum((k*x)^i*cis(i*p*x) for i in 1:N)
        return value
    end

    export build_model
end

using .MyTest2

const list_of_settings = [(N=3,k=0.1,p=0.3),
                    (N=5,k=0.5,p=0.3),
                    (N=7,k=0.2,p=0.3)]
# 
const model = build_model(list_of_settings) # added const
# 
model(2.2; pars=[1,1,1.0])
@code_warntype model(2.2; pars=[1,1,1.0]) # fine, body::Complex{Float64}
#
M(x) = model(x; pars=[1,1,1.0])
@code_warntype M(2.2) # still Body::Any

```

Type is still not inferred. What do I miss?

[Next page](https://discourse.julialang.org/t/code-warntype-understanding/48627.md?page=2)
