# The best way to pass intermediate value to auxiliary functions

**URL:** <https://discourse.julialang.org/t/the-best-way-to-pass-intermediate-value-to-auxiliary-functions/80254>\
**Category:** Performance\
**Tags:** function\
**Created:** [April 29, 2022, 12:50pm UTC](https://discourse.julialang.org/t/the-best-way-to-pass-intermediate-value-to-auxiliary-functions/80254 "2022-04-29T12:50:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![wujinq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wujinq/32/22221_2.png) [@wujinq](https://discourse.julialang.org/u/wujinq)\
**Post date:** [April 29, 2022, 12:50pm UTC](https://discourse.julialang.org/t/the-best-way-to-pass-intermediate-value-to-auxiliary-functions/80254/1 "2022-04-29T12:50:54Z")

</div>

I’m writing a Monte Carlo program and I need a lot of auxiliary function dependent on one or two fields of the parameter `model` of the main function `sweep!(model)` in the following way:

```julia
function sweep!(model, n_sweep)
    α = some_expression_of_parameters_in(model)
    β = some_other_expression_of_parameters_in(model)
    # ... 
    # α, β, ... don't change in the following code
    #...
    for _ in 1 : n_sweep
        my_auxiliary_function() # The definition of the function is dependent on α, β, ...
    end
end

```

The auxiliary functions are called in each loop of sweeping, so I want them to be as fast as possible. Currently I define them in `sweep!`, so that `α`, `β`, … aren’t passed through the parameters of `my_auxiliary_function`. This is not very readable (causing `sweep!` to be a 300-line function), so I want to define `my_auxiliary_function` outside.

But here comes the problem of how to pass `α`, `β`, … to `my_auxiliary_function`. I will frequently change the number and definition of these quantities, and `my_auxiliary_function` appears in multiple places, so if I just define `my_auxiliary_function` as `my_auxiliary_function(α, β, ..., other_parameters)`, whenever I change the number and definition of `α`, `β`, …, I need to change all `my_auxiliary_function`. Besides, since `α`, `β`, … never change after they are calculated, this kind of calling convention is rather distracting.

I can also build a `struct` to contain `α`, `β`, …, and pack these values into one `struct`, and pass the `struct` to `my_auxiliary_function`. But unpacking a `struct` takes time.

What should I do, then, to move `my_auxiliary_function` out of `sweep!`?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [April 29, 2022, 2:10pm UTC](https://discourse.julialang.org/t/the-best-way-to-pass-intermediate-value-to-auxiliary-functions/80254/2 "2022-04-29T14:10:55Z")

</div>

Create a `struct`, you comment

> But unpacking a struct takes time.

what is your empirical base for it? If the `struct` is immutable, then unpacking is basically aliasing a address in the stack and incurs in no runtime penalty (maybe slightly more compilation time). If you struct is mutable each unpacked field is just one pointer de-reference to a value probably already in L1 cache; is your auxiliary function so lightweight that this de-reference is a considerable overhead?

---

<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:** [April 29, 2022, 2:19pm UTC](https://discourse.julialang.org/t/the-best-way-to-pass-intermediate-value-to-auxiliary-functions/80254/3 "2022-04-29T14:19:15Z")

</div>

Why not just define a closure (or a similar callable object) and pass around that? For example, define:

```julia
function sweep!(model, n_sweep)
    for _ in 1:n_sweep
        model()
    end
end

```

and then call it as e.g.

```julia
sweep!(() -> my_auxiliary_function(α, β, ..., other_parameters), n_sweep)

```

or even (using Julia’s nice `do` syntax) as:

```julia
sweep!(n_sweep) do
    my_auxiliary_function(α, β, ..., other_parameters)
end

```

This way, you let the [anonymous function (closure)](https://en.wikipedia.org/wiki/Closure_(computer_programming)) “capture” all of the parameters that you need and pass them through to `sweep!` or whatever other functions might need to call your model, and you can change the model as much as you want while leaving `sweep!` unchanged.

There are lots of examples of this sort of [higher-order function](https://en.wikipedia.org/wiki/Higher-order_function) in Julia (and other languages). e.g. a close relative of Monte-Carlo methods is numerical integration (“quadrature”), in which you have a function of the form `integrate(f, a, b)` that computes \int\_a^b f(x)dx. If you want to pass additional parameters to your integrand you just use a closure `integrate(x -> f(x, params...), a,b)`.
