# Distinguishing anonymous functions inside types

**URL:** <https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216>\
**Category:** General Usage\
**Created:** [February 26, 2019, 3:14pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216 "2019-02-26T15:14:46Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 3:14pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/1 "2019-02-26T15:14:46Z")

</div>

Suppose I do the following (extracted from actual code):

```julia
julia> struct MyTest{F}
           f::F
       end

julia> function initialize(x::T) where {T}
           return MyTest(i->(i==0) ? x : zero(x))
       end
initialize (generic function with 1 method)

julia> x = initialize(1.0)
MyTest{getfield(Main, Symbol("##5#6")){Float64}}(getfield(Main, Symbol("##5#6")){Float64}(1.0))

julia> y = initialize(2.0)
MyTest{getfield(Main, Symbol("##5#6")){Float64}}(getfield(Main, Symbol("##5#6")){Float64}(2.0))

julia> typeof(x) == typeof(y)
true

```

I was not expecting the anonymous functions to be the _same_ and hence the types to be the same. I in fact need these two types to be _different_. How can I achieve this?

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [February 26, 2019, 4:05pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/2 "2019-02-26T16:05:31Z")

</div>

This works:

```julia
julia> struct MyTest{F}
           f::F
       end

julia> function initialize(::Val{x}) where {x}
           return MyTest(i->(i==0) ? x : zero(x))
       end
initialize (generic function with 1 method)

julia> x = initialize(Val(1.0))
MyTest{getfield(Main, Symbol("##5#6")){1.0}}(getfield(Main, Symbol("##5#6")){1.0}())

julia> y = initialize(Val(2.0))
MyTest{getfield(Main, Symbol("##5#6")){2.0}}(getfield(Main, Symbol("##5#6")){2.0}())

julia> typeof(x) == typeof(y)
false

```

but I’d be also interested to hear why OPs only constructs one function.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 4:56pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/3 "2019-02-26T16:56:49Z")

</div>

This seems to be a bug to me: the two functions are actually different:

```julia
julia> x.f(0)
1.0

julia> y.f(0)
2.0

```

So they should not be given the same name.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 5:03pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/4 "2019-02-26T17:03:08Z")

</div>

[https://github.com/JuliaLang/julia/issues/31181](https://github.com/JuliaLang/julia/issues/31181)

---

<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:** [February 26, 2019, 5:06pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/5 "2019-02-26T17:06:47Z")

</div>

No this is not a bug. This is exactly how closures should behave. Their type does not carry all the information about their behavior

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 5:23pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/6 "2019-02-26T17:23:59Z")

</div>

Hmm. I had in my head the idea that distinct functions had distinct types. (Apparently I was wrong.)

Can you suggest a solution for my original question in that case?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 5:25pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/7 "2019-02-26T17:25:31Z")

</div>

Also I thought that each time an anonymous function was created, it automatically had a new type.

---

<div class="post-metadata">

**Author:** ![zgornel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zgornel/32/217487_2.png) [@zgornel](https://discourse.julialang.org/u/zgornel)\
**Post date:** [February 26, 2019, 6:05pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/8 "2019-02-26T18:05:25Z")

</div>

Maybe this may help

```julia
function initialize2(::Val{x}) where {x}
   @eval foo=i->(i==0) ? $x : zero($x)
   return MyTest(foo)
end

```

I suppose the anonymous function gets parsed once in `initialize` and any subsequent calls to `initialize` just recall the same defined symbol… This should solve it by explicitly redefining a new function to be passed to the constructor.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [February 26, 2019, 6:14pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/9 "2019-02-26T18:14:14Z")

</div>

Luckily not! Consider

```julia
ret = 0
n = 10
for i = 1 : n
    f = () -> 2 * i
    global ret += f()
end

```

Compile time would scale with `n`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 26, 2019, 6:56pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/10 "2019-02-26T18:56:22Z")

</div>

> [@dpsanders](#):
>
> Can you suggest a solution for my original question in that case?

You could keep a global counter and include it in the `struct`, or have an explicit

```julia
struct XTester{T}
    x::T
end

(f::XTester)(i) = i == 0 ? f.x : zero(f.x)

```

but it is hard to say more without context.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 26, 2019, 7:37pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/11 "2019-02-26T19:37:50Z")

</div>

Here’s the deal: it’s each _location_ where you write an anonymous function that a new type gets created. The anonymous function is created by syntax lowering. (If you’re really curious, you can see how the anonymous function works with `Meta.@lower function initiialize ...`, but it’s messy). The struct that describes the anonymous function is “lifted” out of `initialize` and created at the same time that the `initialize` function is created.

The anonymous function that `initialize` returns is a closure around the argument you pass. In fact, you can even pull out the captured variable with normal field access:

```julia
julia> t = initialize(2)
MyTest{getfield(Main, Symbol("##5#6")){Int64}}(getfield(Main, Symbol("##5#6")){Int64}(2))

julia> t.f.x
2

julia> t = initialize(1//2)
MyTest{getfield(Main, Symbol("##5#6")){Rational{Int64}}}(getfield(Main, Symbol("##5#6")){Rational{Int64}}(1//2))

julia> t.f.x
1//2

```

Also note how the anonymous function is parameterized by the type of the captured variable — that’s so it can be fast and type-stable. Even in the parametric case that @mauro3 describes above, you’re just creating one type for the anonymous function — it’s just that the exact _value_ is known at compile time and so it’s used as the parameter itself.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 8:24pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/12 "2019-02-26T20:24:33Z")

</div>

Great explanation, thanks!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 9:05pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/13 "2019-02-26T21:05:26Z")

</div>

[quote=“mauro3, post:2, topic:21216”]

This almost works, but

```julia
julia> z = initialize(Val(1.0))
MyTest{getfield(Main, Symbol("##3#4")){1.0}}(getfield(Main, Symbol("##3#4")){1.0}())

julia> x == z
true

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 26, 2019, 9:17pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/14 "2019-02-26T21:17:25Z")

</div>

I guess the big question is why do you need these to compare different? They’ll behave identically. Of course if `MyTest` is mutable it will create a new object each time. You could also throw a simple mutable anonymous function wrapper in between `MyTest` and the function to achieve this:

```julia
julia> struct MyTest{F}
           f::F
       end

julia> mutable struct F{FF}
           f::FF
       end
       (f::F)(x...) = f.f(x...)

julia> function initialize(x)
           return MyTest(F(i->(i==0) ? x : zero(x)))
       end
initialize (generic function with 1 method)

julia> initialize(1) == initialize(1)
false

```

The types are still the same, but now equality is different.

---

<div class="post-metadata">

**Author:** ![jeff.bezanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff.bezanson/32/48_2.png) [@jeff.bezanson](https://discourse.julialang.org/u/jeff.bezanson)\
**Post date:** [February 26, 2019, 9:38pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/15 "2019-02-26T21:38:28Z")

</div>

If you really want a new function type each time, call `eval`. But as others have mentioned, this could cause compile time issues.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 26, 2019, 10:28pm UTC](https://discourse.julialang.org/t/distinguishing-anonymous-functions-inside-types/21216/16 "2019-02-26T22:28:51Z")

</div>

These functions give the coefficients of a Taylor series;  
they effectively encode the AST of a composite function.

I think / thought that I need them to be different objects since

they are put in an array which is then manipulated and in which

the new objects created are of different types.

But thinking about it now, all I need to do is change the type of the array that is created.

In any case, I learned a lot; thanks to all for the comments and explanations!
