# Better ways of passing functions around?

**URL:** <https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971>\
**Category:** Performance\
**Created:** [October 30, 2018, 2:53pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971 "2018-10-30T14:53:44Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 30, 2018, 2:53pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/1 "2018-10-30T14:53:44Z")

</div>

When I pass function around, it causes a huge memory allocation. Like the following:

```nohighlight
        - function f1(x::Float64)
 16000000 x = x+3.
        - end 
        - 
        - mutable struct MyType
        - x::Float64
        - func::Function
        - 	
        - function MyType(x::Float64)
     2208 this = new()
        - this.x = x
        - this
        - end
        - end
        - 
        - function main()
        - t1 = MyType(3.)
        0 t1.func = f1
        - 	
        0 for i=1:1000000
 48000000 t1.x = t1.func(i*0.1)
        - end
        - end

```

But if I call it directly, there seems no problem:

```julia
        - function main1()
        - t1 = MyType(3.)
        - 
     2176 for i=1:1000000
        0 t1.x = f1(i*0.1)
        - end
        - end

```

Can anyone please help explain? How can I better pass function around?

---

<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:** [October 30, 2018, 2:58pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/2 "2018-10-30T14:58:22Z")

</div>

You need to parameterize it for Julia to be able to infer it:

```julia
mutable struct MyType{F<:Function}
  func::F
end

```

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 30, 2018, 11:10pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/3 "2018-10-30T23:10:14Z")

</div>

That unfortunately doesn’t help.

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 30, 2018, 11:18pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/4 "2018-10-30T23:18:19Z")

</div>

I did some further test, with the script below:

```julia
function f1(x::Float64)
	x = x+3.
end 

mutable struct MyType{F<:Function}
	x::Float64
	func::F
	funcs::Array{Function,1}
	sf::Symbol
	
	function MyType{F}(x::Float64) where {F<:Function}
		this = new()
		this.x = x
		this.funcs = Array{Function,1}(undef,1)
		this
	end
end 

function main()
	t1 = MyType{Function}(3.)
	t1.func = f1
	
	for i=1:1000000
		t1.x = t1.func(i*0.1)
	end
end

function main1()
	t1 = MyType{Function}(3.)

	for i=1:1000000
		t1.x = f1(i*0.1)
	end
end

function main2()
	t1 = MyType{Function}(3.)
	f = f1
	
	for i=1:1000000
		t1.x = f(i*0.1)
	end
end

function main3()
	t1 = MyType{Function}(3.)
	t1.sf = :f1
	f = getfield(Main, t1.sf)
	
	for i=1:1000000
		t1.x = f(i*0.1)
	end
end

function main4()
	t1 = MyType{Function}(3.)
	aDict = Dict{String, Function}()
	aDict["f1"] = f1
	f = get(aDict, "f1", 0)
	
	for i=1:1000000
		t1.x = f(i*0.1)
	end
end

function main5()
	t1 = MyType{Function}(3.)
	f = include_string(Main, "f1")
	
	for i=1:1000000
		t1.x = f(i*0.1)
	end
end
	
function main6(ff::Function)
	t1 = MyType{Function}(3.)
	
	for i=1:1000000
		t1.x = ff(i*0.1)
	end
end

function main7()
	t1 = MyType{Function}(3.)
	t1.funcs[1] = f1
	
	for i=1:1000000
		t1.x = t1.funcs[1](i*0.1)
	end
end

```

```julia
julia> using BenchmarkTools

julia> @btime main()
  133.799 ms (4000001 allocations: 61.04 MiB)

julia> @btime main1()
  1.640 ns (0 allocations: 0 bytes)

julia> @btime main2()
  1.640 ns (0 allocations: 0 bytes)

julia> @btime main3()
  133.398 ms (4000001 allocations: 61.04 MiB)

julia> @btime main4()
  134.623 ms (4000005 allocations: 61.04 MiB)

julia> @btime main5()
  136.345 ms (4000002 allocations: 61.04 MiB)

julia> @btime main6(f1)
  1.640 ns (0 allocations: 0 bytes)

julia> @btime main7()
  140.606 ms (4000002 allocations: 61.04 MiB)

```

So it look only “main6” may be not so prohibitive for passing functions. Are there other options please?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 30, 2018, 11:53pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/5 "2018-10-30T23:53:49Z")

</div>

What are you actually trying to do?

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 30, 2018, 11:59pm UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/6 "2018-10-30T23:59:18Z")

</div>

I need to call a function among a list of functions. Some other routine determines which is the function to call, and so it needs to be passed from there.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 31, 2018, 12:01am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/7 "2018-10-31T00:01:01Z")

</div>

Based on what? How is the function selected? What is the set of functions? Where do they come from?

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 31, 2018, 12:10am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/8 "2018-10-31T00:10:49Z")

</div>

The functions are defined in a couple of .jl files. They are quite simple and with the same signature. A routine selects one or a few based on some attributes that can be preset or by user input. Based on the selection, the other routine calls them. So in some way, I need to get the functions passed from one routine to the other.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 31, 2018, 12:15am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/9 "2018-10-31T00:15:48Z")

</div>

Your explanation (not original post) doesn’t explain why you are putting a bunch of functions in a `Vector` and not

```julia
if x
   call_foo()
elseif y
   call_bar()
...

```

If you want this to be dynamic (and your functions are quick enough to not offset the dynamic dispatch) then something like [GitHub - yuyichao/FunctionWrappers.jl](https://github.com/yuyichao/FunctionWrappers.jl) is probably your best bet.

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 31, 2018, 12:18am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/10 "2018-10-31T00:18:16Z")

</div>

I can’t do the if statement, because there are too many functions.

I will check about the link. Thanks

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 31, 2018, 12:52am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/11 "2018-10-31T00:52:55Z")

</div>

Compared with “main2”, what is the cause of increased costs in “main” and “main7”?

---

<div class="post-metadata">

**Author:** ![oliver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oliver/32/19264_2.png) [@oliver](https://discourse.julialang.org/u/oliver)\
**Post date:** [October 31, 2018, 2:07am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/12 "2018-10-31T02:07:48Z")

</div>

How did you generate the left column of memory allocations?

---

<div class="post-metadata">

**Author:** ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)\
**Post date:** [October 31, 2018, 2:13am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/13 "2018-10-31T02:13:48Z")

</div>

> [@oliver](#):
>
> How did you generate the left column of memory allocations?

`Julia --track-allocation=user`

check with “Memory allocation analysis” section in Julia docs

---

<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:** [October 31, 2018, 2:15am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/14 "2018-10-31T02:15:55Z")

</div>

FunctionWrappers is unfortunately quite broken on 1.0. @yuyichao says it’s a Base bug, see [https://github.com/yuyichao/FunctionWrappers.jl/issues/8](https://github.com/yuyichao/FunctionWrappers.jl/issues/8), [cfunction issue with FunctionWrappers · Issue #28669 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/28669).

---

<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:** [October 31, 2018, 8:04am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/15 "2018-10-31T08:04:35Z")

</div>

Easiest and pretty fast, but not 100% performant is:

```julia
function foo(list_of_functions::Vector, arg)
  out = 0.0
  for f in list_of_functions
    out += f(arg)::Float64 # annotate the return type
  end
  out
end

```

If that is not sufficient and FunctionWrappers.jl is not working, then some lispy recursion on your functions (stored in a tuple) might be able to do the trick.

---

<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:** [October 31, 2018, 8:20am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/16 "2018-10-31T08:20:00Z")

</div>

If there is any common pattern in the functions, I would suggest using a _single_ function and parametrize on eg `Val`. For example,

```julia
function foo(::Val{:F1}, other, arguments)
    ...
end

function foo(::Val{:F2}, other, arguments)
    ...
end

```

If the other arguments have an irregular structure, pack them in a `NamedTuple`. Then just use `Val{T}()` to select. This could be returned by the function which decides the function to be called.

_(as others have noted, more information and an MWE would of course allow more specific suggestions)_

---

<div class="post-metadata">

**Author:** ![y4lu](https://avatars.discourse-cdn.com/v4/letter/y/47e85d/32.png) [@y4lu](https://discourse.julialang.org/u/y4lu)\
**Post date:** [October 31, 2018, 11:17am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/17 "2018-10-31T11:17:45Z")

</div>

does immutable structs perform better?

```julia
function f1(x::Float64)
  return x + 3; ##x = x+3
  end 

struct MyType
  x::Float64
  func::Function
  end ## Default constructor is MyType(x::Float64, func::Function)

function main()
  t1 = MyType(3., f1)
  for i=1:1000000
     t1.x += t1.func(i*0.01) #t1.x = t1.func(i*0.1)
    end
  end

```

-add: there’s still a bit of funny business with the `x = `  
and to be sure the compiler doesn’t optimize out the loop, re- 1 million iter in 1.6ns with main6()

Handy rule of thumb is that Ghz is ticks per nanosecond

---

<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:** [October 31, 2018, 11:23am UTC](https://discourse.julialang.org/t/better-ways-of-passing-functions-around/16971/18 "2018-10-31T11:23:31Z")

</div>

You can test that for yourself using BenchmarkTools.jl `@btime`. But the answer, I assume, is no. Julia still cannot infer which function is held by t1.func and thus needs to box things and thus allocations will happen.
