# Question on Type Inference with Anonymous Functions and Broadcast

**URL:** <https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102>\
**Category:** General Usage\
**Created:** [March 18, 2022, 6:31pm UTC](https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102 "2022-03-18T18:31:52Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [March 18, 2022, 6:31pm UTC](https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102/1 "2022-03-18T18:31:52Z")

</div>

Hello!

I have a question. Consider this function.

```julia
f(x) = exp(2 * x)
x = range(0, 1, 2^5)

```

If I want to pass `x` into it I would do `f.(x)` and if I do `@code_warntype` I can see everything is inferred.

```julia
Body::Vector{Float64}
1 ─ %1 = Base.broadcasted(Main.f, x1)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(f), Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}
│ %2 = Base.materialize(%1)::Vector{Float64}
└── return %2

```

If I create an anonymous function from `f` though and try to broadcast I get type `Any`.

```julia
h = x -> f(x)
@code_warntype h.(x)

```

The result is

```julia
Body::Any
1 ─ %1 = Base.broadcasted(Main.h, x1)::Any
│ %2 = Base.materialize(%1)::Any
└── return %2

```

I would appreciate any hints on what is happening here with broadcasting to cause the `Any`.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [March 18, 2022, 6:51pm UTC](https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102/2 "2022-03-18T18:51:11Z")

</div>

```julia
julia> x = range(0, 1, 2^5)
0.0:0.03225806451612903:1.0

julia> f(x) = exp(2 * x)
f (generic function with 1 method)

julia> @code_warntype (x -> f(x)).(x)
MethodInstance for (::var"##dotfunction#291#2")(::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64})
  from (::var"##dotfunction#291#2")(x1) in Main
Arguments
  #self#::Core.Const(var"##dotfunction#291#2"())
  x1::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}
Locals
  #1::var"#1#3"
Body::Vector{Float64}
1 ─ (#1 = %new(Main.:(var"#1#3")))
│ %2 = #1::Core.Const(var"#1#3"())
│ %3 = Base.broadcasted(%2, x1)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, var"#1#3", Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}
│ %4 = Base.materialize(%3)::Vector{Float64}
└── return %4

julia> const h = x -> f(x)
#4 (generic function with 1 method)

julia> @code_warntype h.(x)
MethodInstance for (::var"##dotfunction#292#6")(::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64})
  from (::var"##dotfunction#292#6")(x1) in Main
Arguments
  #self#::Core.Const(var"##dotfunction#292#6"())
  x1::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}
Body::Vector{Float64}
1 ─ %1 = Base.broadcasted(Main.h, x1)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, var"#4#5", Tuple{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}}
│ %2 = Base.materialize(%1)::Vector{Float64}
└── return %2

```

so as you can see the problem is that in your code the binding `h = x -> f(x)` is not a constant (the type of value bound to `h` might change).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 18, 2022, 7:37pm UTC](https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102/3 "2022-03-18T19:37:54Z")

</div>

> [@bkamins](#):
>
> as you can see the problem is that in your code the binding `h = x -> f(x)` is not a constant (the type of value bound to `h` might change).

In particular, it’s a non-constant **global** variable, which is always slow in Julia—this is the very [first performance tip](https://docs.julialang.org/en/v1/manual/performance-tips/#Performance-critical-code-should-be-inside-a-function) in the manual.

If you use anonymous functions **locally** inside a function or other local scope, they are just fine.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [March 18, 2022, 7:42pm UTC](https://discourse.julialang.org/t/question-on-type-inference-with-anonymous-functions-and-broadcast/78102/4 "2022-03-18T19:42:55Z")

</div>

Yes good points. Totally missed that that was the issue here.
