# Arrays of functions

**URL:** <https://discourse.julialang.org/t/arrays-of-functions/46549>\
**Category:** New to Julia\
**Tags:** function\
**Created:** [September 13, 2020, 3:37pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549 "2020-09-13T15:37:19Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![aerdely](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aerdely/32/37506_2.png) [@aerdely](https://discourse.julialang.org/u/aerdely)\
**Post date:** [September 13, 2020, 3:37pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/1 "2020-09-13T15:37:19Z")

</div>

About the following code:

```julia
f(x) = 2x + 1
g(x) = x^2
h(x) = x^3 
I = [f, g, h]
J = Array{Function, 2}(undef, 3, 3)
for i ∈ 1:3
    for j ∈ 1:3
        J[i, j] = I[i] ∘ I[j]
    end
end
display(J)

```

I get:

```julia
3×3 Array{Function,2}:
 #62 #62 #62
 #62 #62 #62
 #62 #62 #62

```

Everything works fine and I can use any of the functions in the array, obtaining the expected evaluations, for example:

```julia
julia> J[1,2](5)
51

```

But why a `#62` when displaying the `J` array or its elements? Just curious about it:

```julia
julia> J[1,2]
#62 (generic function with 1 method)

```

Or in more detail:

```julia
julia> println(J)
Function[Base.var"#62#63"{typeof(f),typeof(f)}(f, f) Base.var"#62#63"{typeof(f),typeof(g)}(f, g) Base.var"#62#63"{typeof(f),typeof(h)}(f, h); Base.var"#62#63"{typeof(g),typeof(f)}(g, f) Base.var"#62#63"{typeof(g),typeof(g)}(g, g) Base.var"#62#63"{typeof(g),typeof(h)}(g, h); Base.var"#62#63"{typeof(h),typeof(f)}(h, f) Base.var"#62#63"{typeof(h),typeof(g)}(h, g) Base.var"#62#63"{typeof(h),typeof(h)}(h, h)]

```

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [September 13, 2020, 3:39pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/2 "2020-09-13T15:39:29Z")

</div>

This is how anonymous functions work in general and the composition operator generates anonymous functions:

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

julia> g(x) = x^2
g (generic function with 1 method)

julia> f ∘ g
#62 (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![aerdely](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aerdely/32/37506_2.png) [@aerdely](https://discourse.julialang.org/u/aerdely)\
**Post date:** [September 13, 2020, 3:43pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/3 "2020-09-13T15:43:34Z")

</div>

But why the use of a specific number such as `#62`?

---

<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:** [September 13, 2020, 4:16pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/4 "2020-09-13T16:16:13Z")

</div>

> [@johnmyleswhite](#):
>
> the composition operator generates anonymous functions:

(note that this will change in 1.6:

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

julia> g(x) = x^2
g (generic function with 1 method)

julia> f ∘ g
f ∘ g

julia> typeof(ans)
Base.ComposedFunction{typeof(f), typeof(g)}

```

It’s only an implementation detail though, so it should still behave completely the same.)

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [September 13, 2020, 4:21pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/5 "2020-09-13T16:21:24Z")

</div>

The name is generated within the compiler by the function `gensym` or an equivalent. `gensym` creates symbols which are unique in that no two calls to `gensym` will produce the same symbol. This is in some most part done by iterating a number. There is also the symbol `#` which is difficult to get into a symbol unless you are using the symbol constructor or the `@var_str` macro presumably `gensym` has been used 61 times before here.

---

<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:** [September 13, 2020, 4:27pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/6 "2020-09-13T16:27:24Z")

</div>

You can actually really easily define `∘` yourself. In fact, this is exactly how it’s defined in Julia 1.5:

```julia
julia> f ∘ g = (x...) -> f(g(x...))
∘ (generic function with 1 method)

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

julia> g(x) = x^2
g (generic function with 1 method)

julia> f ∘ g
#7 (generic function with 1 method)

julia> (f ∘ g)(3)
19

```

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 13, 2020, 9:11pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/7 "2020-09-13T21:11:18Z")

</div>

Seems like in julia 1.5, functions constructed with composition are always named #62#63

```julia
julia> f ∘ g
#62 (generic function with 1 method)

julia> sum ∘ prod
#62 (generic function with 1 method)

julia> typeof(ans)
Base.var"#62#63"{typeof(sum),typeof(prod)}

```

In julia 1.3, for example, it’s #56#57:

```julia
julia> typeof(J[1])
Base.var"#56#57"{typeof(f),typeof(f)}

julia> typeof(sum ∘ prod)
Base.var"#56#57"{typeof(sum),typeof(prod)}

```

🤷‍♂️

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 14, 2020, 4:52am UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/8 "2020-09-14T04:52:25Z")

</div>

`#62` maybe there are already 61 things before this?

Also, you see how each of these increments the number? `#62` Is just a name which keep incrementing if you assign more variables or define functions that HAVE different signatures.

```julia
()->1

(x)->1

x::Int -> 1

(x, y) -> 1

```

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 14, 2020, 6:35am UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/9 "2020-09-14T06:35:06Z")

</div>

> [@xiaodai](#):
>
> `#62` maybe there are already 61 things before this?

Seems not:

```julia
julia> x->x+1
#1 (generic function with 1 method)

julia> sum ∘ prod
#62 (generic function with 1 method)

julia> x->x+1
#3 (generic function with 1 method)

```

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 14, 2020, 7:58am UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/10 "2020-09-14T07:58:43Z")

</div>

Interesting. The innards of the name assignment will be interesting to know

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [September 14, 2020, 8:34am UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/11 "2020-09-14T08:34:44Z")

</div>

It is the same anonymous function type used each time you use the `∘` operator, just with different parametric function types based on what you pass in.

Behind the scenes all anonymous functions are merely callable structs that inherit from Function. The definition of the struct `Base.var"#56#57"` is created when the function is defined, not when it is called. So internally, when you call `sum ∘ prod` the constructor for the parametric struct `Base.var"#56#57"` is called with whatever functions you passed in.

On the top level what is going on is that each time you enter say `x -> x + 1` a new callable struct is defined.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 14, 2020, 11:57am UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/12 "2020-09-14T11:57:45Z")

</div>

This is really interesting, but it looks like there may be even a bit more going on. Perhaps you know more about this?  
For example, `var"#62#63"` is defined in Base (even when the composition happens in Main) and is a UnionAll, while a “regular” anonymous function defined in Main is defined directly in Main, and is a Datatype. I’m curious to know more about this though; do you know where this distinction happens, or where in Base the definition of var"#62#63" (the parametric struct) happens?  
See:

```julia
julia> typeof(x -> x + 1)
var"#33#34"

julia> typeof(ans)
DataType

julia> typeof(sum ∘ prod ∘ sum)
Base.var"#62#63"{Base.var"#62#63"{typeof(sum),typeof(prod)},typeof(sum)}

julia> typeof(Base.var"#62#63")
UnionAll

julia> var"#62#63"
ERROR: UndefVarError: #62#63 not defined

```

Like you said, it seems like composition creates an instance of a parameterized anonymous struct that is defined in Base somewhere (I couldn’t find the root cause of the name with a quick skim). This is somewhat surprising to me, since there doesn’t seem to be anything special in the source of `∘` that suggests it would always return an instance of a particular `UnionAll` anonymous function, since other anonymous functions don’t do that. I.e. the identical version defined [in a previous comment above](https://discourse.julialang.org/t/arrays-of-functions/46549/6) (in Main, which is perhaps notable) has a normal upwards-counting gensym name.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [September 14, 2020, 12:16pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/13 "2020-09-14T12:16:15Z")

</div>

I know there is a `gen_sym()` function. Perhaps it’s involved somehow

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 14, 2020, 12:30pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/14 "2020-09-14T12:30:17Z")

</div>

Yes, it certainly is in generating the name, but the parametric behavior is still unusual (to me…).  
This is quickly getting way over my head though. What the heck is `:thunk`?

```julia
julia> Meta.@lower (x...) -> f(g(x...))
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ $(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ global var"#49#50"
│ const var"#49#50"
│ %3 = Core._structtype(Main, Symbol("#49#50"), Core.svec(), Core.svec(), false, 0)
│ var"#49#50" = %3
│ Core._setsuper!(var"#49#50", Core.Function)
│ Core._typebody!(var"#49#50", Core.svec())
└── return
)))
│ %2 = var"#49#50"
│ %3 = Core.apply_type(Vararg, Core.Any)
│ %4 = Core.svec(%2, %3)
│ %5 = Core.svec()
│ %6 = Core.svec(%4, %5, $(QuoteNode(:(#= REPL[308]:1 =#))))
│ $(Expr(:method, false, :(%6), CodeInfo(quote
    Core._apply_iterate(Base.iterate, g, x)
    f(%1)
    return %2
end)))
│ #49 = %new(var"#49#50")
└── return #49
))))

```

[Who knew…?](https://en.wikipedia.org/wiki/Thunk)

---

<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:** [September 14, 2020, 1:21pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/15 "2020-09-14T13:21:46Z")

</div>

While the term is well-known inside CS, specific usage for Julia ASTs is (yet) [undocumented](https://docs.julialang.org/en/v1.6-dev/devdocs/ast/).

---

<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:** [September 14, 2020, 1:25pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/16 "2020-09-14T13:25:38Z")

</div>

This is just how closures work. `x -> x + 1` doesn’t contain any external variables, so the closure doesn’t need to contain any fields, therefore `var"#33#34"` is just a `DataType`. `(x...) -> f(g(x...))` depends on how `f` and `g` are defined though, so `f` and `g` need to be stored as fields of the closure. Because `f` and `g` can have all kinds of types, for this to be type stable, the type of the closure needs to be a `UnionAll` over arbitrary types for `f` and `g`. So `closure = x -> x + 1` would be equivalent to:

```julia
struct var"#1#2"
end
(::var"#1#2")(x) = x + 1
const var"#1" = var"#1#2"()
closure = var"#1"

```

Whereas `closure = (x...) -> f(g(x...))` would be the equivalent of

```julia
struct var"#3#4"{F,G}
    f::F
    g::G
end
(var"#3"::var"#3#4")(x...) = (var"#3".f)((var"#3".g)(x...))
closure = var"#3#4"{typeof(f),typeof(g)}(f, g)

```

---

<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:** [September 14, 2020, 1:31pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/17 "2020-09-14T13:31:10Z")

</div>

Thunks are only produced in lowering and they are necessary because new struct types cannot be defined in local scope, struct types are always global constants. Therefore thunks tell later steps in the compiler to move the definition of the closure type out of the scope the closure was initially created in in a way that doesn’t cause the struct to be defined in a newer worldage. The struct type will always be created in the module the closure was initially created in, so for `∘`, that’s in Base.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 14, 2020, 2:08pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/18 "2020-09-14T14:08:22Z")

</div>

> [@simeonschaub](#):
>
> So `closure = x -> x + 1` would be equivalent to: […]  
> Whereas `closure = (x...) -> f(g(x...))` would be the equivalent of […]

This is right (see below) but it’s not what you see in the global scope, which threw me off. Presumably, since f and g are global constants rather than local bindings in the same namespace, this changes how the closure is handled.

```julia
julia> (x...) -> f(g(x...)) # same as ∘ def
#83 (generic function with 1 method)

julia> typeof(ans) # handled differently from ∘
var"#83#84"

julia> typeof(f∘g)
Base.var"#62#63"{typeof(f),typeof(g)}

```

suggested there is something different going on, but

```julia
julia> function comp(f, g)
          (x...) -> f(g(x...))
       end
comp (generic function with 1 method)

julia> typeof(comp(f, g))
var"#89#90"{typeof(f),typeof(g)}

julia> typeof(comp(h, g))
var"#89#90"{typeof(h),typeof(g)}

```

shows it’s a scope thing. Both have #89#90, and the type parameters, consistent with `∘`

---

<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:** [September 14, 2020, 2:19pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/19 "2020-09-14T14:19:36Z")

</div>

Yes, that is because in your first example, `f` and `g` are globals, they aren’t in a local scope, so the closure just references `Main.f` and `Main.g` and doesn’t need to store them as fields. Try:

```julia
let f=f, g=g
    (x...) -> f(g(x...))
end

```

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 14, 2020, 2:34pm UTC](https://discourse.julialang.org/t/arrays-of-functions/46549/20 "2020-09-14T14:34:07Z")

</div>

> [@simeonschaub](#):
>
> ```julia
> let f=f, g=g
> (x...) -> f(g(x...))
> end
> 
> ```

Yep, I executed exactly that example after going through the above 😜
