# Pass functions to objects

**URL:** <https://discourse.julialang.org/t/pass-functions-to-objects/71505>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [November 15, 2021, 4:01pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505 "2021-11-15T16:01:37Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:01pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/1 "2021-11-15T16:01:38Z")

</div>

Hi everyone,

I’m new to Julia and writing a particle simulation. Each System of Particles should have a set of functions that update the forces acting on the system/particles. These functions should be user definable. I don’t know how to solve this problem properly. Currently I’m using a tuple that contains the functions that should be called:

```julia
mutable struct System
    ps::Vector{Particle}
    forces::Tuple
end

```

and then calling them like:

```julia
function updateForces!(s::System)
    for force in s.forces
        force(s)
    end
end

```

This however is slow compared to calling the functions directly. `@benchmark` reports 350ns with 0 allocations vs 430ns with 0 allocations when using 2 custom functions for `s.forces`.

Is there a better way to do this?

Thank you,  
Nico

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [November 15, 2021, 4:04pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/2 "2021-11-15T16:04:34Z")

</div>

Tuple is an abstract type. Make all fields in `System` concrete. For instance

```julia
mutable struct System{P, F}
    ps::Vector{P}
    forces::Tuple{F, F}
end

```

---

<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:** [November 15, 2021, 4:07pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/3 "2021-11-15T16:07:44Z")

</div>

Looping over functulns tend to be slow because the compiler often cannot devirtualize the call. People usually use [GitHub - yuyichao/FunctionWrappers.jl](https://github.com/yuyichao/FunctionWrappers.jl) to work around that (although I have heard it is slower than needed due to some julia issue).

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [November 15, 2021, 4:13pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/4 "2021-11-15T16:13:00Z")

</div>

> [@kristoffer.carlsson](#):
>
> although I have heard it is slower than needed due to some julia issue

Probably

> <https://github.com/JuliaLang/julia/issues/36977>
>
> Copied from: https://discourse.julialang.org/t/performance-and-memory-regression…-with-function-wrappers-in-julia-1-4/44589
> 
> \### Setup:
> 
> \`\`\`julia
> julia\> using BenchmarkTools
> 
> julia\> using FunctionWrappers: FunctionWrapper
> 
> julia\> w = let closed\_over=(\[1\], \[2\])
> FunctionWrapper{typeof(closed\_over), Tuple{}}(() -\> closed\_over)
> end;
> \`\`\`
> 
> \### Results
> 
> Julia 1.3.1:
> 
> \`\`\`julia
> julia\> @btime $w()
> 5.435 ns (0 allocations: 0 bytes)
> \`\`\`
> 
> Julia 1.4.2:
> 
> \`\`\`julia
> julia\> @btime $w()
> 9.919 ns (1 allocation: 16 bytes)
> \`\`\`
> 
> Julia 1.5.0
> 
> \`\`\`julia
> julia\> @btime $w()
> 10.112 ns (1 allocation: 32 bytes)
> \`\`\`
> 
> Julia 1.6.0-DEV.607
> 
> \`\`\`julia
> julia\> @btime $w()
> 11.846 ns (1 allocation: 32 bytes)
> \`\`\`
> 
> This turns out to be the source of a significant performance regression in Parametron.jl (which was designed to allocate zero memory). 
> 
> Here's my system info:
> 
> \`\`\`
> julia\> versioninfo()
> Julia Version 1.5.0
> Commit 96786e22cc (2020-08-01 23:44 UTC)
> Platform Info:
> OS: Linux (x86\_64-pc-linux-gnu)
> CPU: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
> WORD\_SIZE: 64
> LIBM: libopenlibm
> LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
> \`\`\`
> 
> @yuyichao pointed to https://github.com/yuyichao/FunctionWrappers.jl/issues/14 as a related issue. I cannot reproduce the MWE from https://github.com/yuyichao/FunctionWrappers.jl/issues/14#issuecomment-603379495 on Julia 1.5, but the slowness and extra allocation of my example here is still present in Julia 1.5.0.

?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 15, 2021, 4:19pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/5 "2021-11-15T16:19:17Z")

</div>

Note that this overhead you are observing will be probably irrelevant relative to the cost of computing the functions themselves (it is probably a case of premature optimization).

Take a look at the packages of [JuliaMolSim](https://github.com/JuliaMolSim) and at [CellListMap.jl](https://github.com/m3g/CellListMap.jl), probably there is useful stuff there to you.

@ncxst some ideas about that are available here: [https://github.com/m3g/2021\_FortranCon](https://github.com/m3g/2021_FortranCon)

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:24pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/6 "2021-11-15T16:24:51Z")

</div>

I don’t fully understand the `{}` syntax jet, but as far as I understand it specifies types. Does `forces::Tuple{F, F}` mean that the tuple forces contains 2 objects of type `F`?  
When I try to implement this, I get errors as `forces` contains different functions, e.g. `harmonic!` and `f_d!`:

```julia
julia> System([Particle([0.,0.]) for i in 1:3], (harmonic!, f_d!))
ERROR: MethodError: no method matching System(::Vector{Particle}, ::Tuple{typeof(harmonic!), typeof(f_d!)})
Closest candidates are:
  System(::Vector{P}, ::Tuple{F, F}) where {P, F} at REPL[5]:2

```

Can your code be adapted to accommodate for this?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [November 15, 2021, 4:25pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/7 "2021-11-15T16:25:52Z")

</div>

> [@ncxst](#):
>
> I don’t fully understand the `{}` syntax jet

[https://docs.julialang.org/en/v1/manual/types/#Parametric-Types](https://docs.julialang.org/en/v1/manual/types/#Parametric-Types)

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [November 15, 2021, 4:28pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/8 "2021-11-15T16:28:00Z")

</div>

```julia
mutable struct System{P, F1, F2}
    ps::Vector{P}
    forces::Tuple{F1, F2}
end

```

---

<div class="post-metadata">

**Author:** ![djholiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djholiver/32/50470_2.png) [@djholiver](https://discourse.julialang.org/u/djholiver)\
**Post date:** [November 15, 2021, 4:28pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/9 "2021-11-15T16:28:03Z")

</div>

Aren’t you fighting multiple dispatch a bit here by trying to privately define a set of functions for a struct in a classic object oriented design approach?

What’s preventing you from having the system struct separate to a list of methods that can operate on system structs? You could even define them in a separate module?

Maybe I’m missing the point…

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:30pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/10 "2021-11-15T16:30:51Z")

</div>

Now it allows for 2 types of forces, how can I make it accept any number of forces?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [November 15, 2021, 4:32pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/11 "2021-11-15T16:32:12Z")

</div>

> [@djholiver](#):
>
> What’s preventing you from having the system struct separate to a list of methods that can operate on system structs

Perhaps OP has different functions per instance.

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:33pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/12 "2021-11-15T16:33:23Z")

</div>

I want to have multiple systems where each of them has a different list of forces that act on the system.  
How would I do such a thing with multiple dispatch?

---

<div class="post-metadata">

**Author:** ![djholiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djholiver/32/50470_2.png) [@djholiver](https://discourse.julialang.org/u/djholiver)\
**Post date:** [November 15, 2021, 4:37pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/13 "2021-11-15T16:37:36Z")

</div>

Ok - difficult to discern the need - are you trying to allow users to create their own functions for a particular set of forces? If so, are the System structs not actually structs that inherit from the System Abstract struct?

Then you can have any number of methods to act on a concrete system struct and add them to a collection to do as you first posted.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [November 15, 2021, 4:37pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/14 "2021-11-15T16:37:40Z")

</div>

I think you want to decouple the particles from the system, ie separate the data from the different operations that can act on it.

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:45pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/15 "2021-11-15T16:45:13Z")

</div>

> [@djholiver](#):
>
> are you trying to allow users to create their own functions for a particular set of forces?

Yes

> [@djholiver](#):
>
> If so, are the System structs not actually structs that inherit from the System Abstract struct?

Do you mean, that there should be specific structs that inherit from an abstract struct and specify the functions/forces that should act on the special struct?

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 4:46pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/16 "2021-11-15T16:46:30Z")

</div>

How would the system then know which particles are in it and how to apply the forces on the particles.

---

<div class="post-metadata">

**Author:** ![djholiver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djholiver/32/50470_2.png) [@djholiver](https://discourse.julialang.org/u/djholiver)\
**Post date:** [November 15, 2021, 4:48pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/17 "2021-11-15T16:48:58Z")

</div>

Yes, basically. I’m on my phone but that sounds like that pattern you’re describing: you differentiate the action by the properties of the struct.

This is multiple dispatch if inverted from your original design i.e. they are not all actually “system” structs; they are particular types of system struct

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 15, 2021, 4:54pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/18 "2021-11-15T16:54:51Z")

</div>

What differentiates the different particles? Can that be encoded in the type(s), for example as type parameters, or must each particle _instance_ get an arbitrary list of functions?

If you can design it as the former, you definitely should leverage dispatch instead of the current design.

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 5:02pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/19 "2021-11-15T17:02:43Z")

</div>

So the user would define a custom “system” e.g. `MySystem` and a custom function `updateForces!(s::MySystem)` that calls the forces-function the user wants.  
Then multiple dispatch chooses the appropriate `updateForces!`.  
Do I understand this correctly?

---

<div class="post-metadata">

**Author:** ![ncxst](https://avatars.discourse-cdn.com/v4/letter/n/e47774/32.png) [@ncxst](https://discourse.julialang.org/u/ncxst)\
**Post date:** [November 15, 2021, 5:05pm UTC](https://discourse.julialang.org/t/pass-functions-to-objects/71505/20 "2021-11-15T17:05:13Z")

</div>

I see your point, however the same kind of particles can be trapped in different kinds of traps e.g harmonic or sinusoidal, so there has to be the possibility to have different forces acting in different systems with the same type of particles in it.

[Next page](https://discourse.julialang.org/t/pass-functions-to-objects/71505.md?page=2)
