# Best practice for passing parameters to functions passed as parameters

**URL:** <https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479>\
**Category:** General Usage\
**Tags:** parametric-methods, functional\
**Created:** [August 8, 2022, 2:01pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479 "2022-08-08T14:01:29Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nsquare](https://avatars.discourse-cdn.com/v4/letter/n/779978/32.png) [@nsquare](https://discourse.julialang.org/u/nsquare)\
**Post date:** [August 8, 2022, 2:01pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/1 "2022-08-08T14:01:29Z")

</div>

Hello!

I want to write a general function with several subroutines. I would like this method to be able to use different functions as subroutines, by taking them as parameters, as shown in the toy example below.

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function,
                    update!::Function)
    A = preprocess(input)

    # Some common code
    # [...]

    for i in 1:100
        # Some common code
        # [...]
        updater!(A)
    end

    # Some common code
    # [...]

    return A
end

```

My motivation is that a big part of the code will be common and only the preprocess and the updater will be specific.

My question is: how can I pass parameters to `preprocess` and `updater!`, if the different options for these subroutines take different parameters? For example I have one preprocesser that takes no parameter, another that takes one Integer, another that takes a matrix, etc.

I would like to know what is the best practice in this case, in terms of “standard Julia style”, performance, and readibility.

The options I see are:

1. Duplicate the code, write specific versions of `myfunction` and do not pass functions as parameters
2. Have a big structure holding all possible parameters for all differents preprocessers, pass it as a parameter in `myfunction` and in `A = preprocess(input, param_struct)` and make each preprocesser use only the ones it needs.
3. Do some kind of homemade curryfication, where I specialize a preprocesser with its parameters before passing it to `myfunction`.

All these options seem unsatisfying to me, so maybe I’m asking the wrong question and I should see the problem another way. Anyway I would be very thankful for any help, comment, or advice.

Thanks for reading, and please ask if something is not clear!

Nicolas

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 8, 2022, 3:06pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/2 "2022-08-08T15:06:18Z")

</div>

I guess the key question is where those parameters are coming from and how you want to manage them. From your description it seems like you could just do

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function,
                    preprocess_args::Tuple,
                    updater!::Function,
                    updater_args::Tuple
                    )
    A = preprocess(input, preprocess_args...)

    # Some common code
    # [...]

    for i in 1:100
        # Some common code
        # [...]
        updater!(A, updater_args...)
    end

    # Some common code
    # [...]

    return A
end

```

but I might be missing something.

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [August 8, 2022, 3:20pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/3 "2022-08-08T15:20:30Z")

</div>

Maybe you could use keyword arguments [Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#Keyword-Arguments)

The differences to optional arguments is that the order doesn’t matter but only the keywords. Notices that one uses `;` instead of `,` to capture keyword argument lists.  
E.g.

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function,
                    updater!::Function;
                    args...
                    )
    A = preprocess(input; args...)

    # Some common code
    # [...]

    for i in 1:100
        # Some common code
        # [...]
        updater!(A; args...)
    end

    # Some common code
    # [...]

    return A
end

```

For the user calling your function it is enough to write

```julia
myfunction(input, preprocess, updater!, alpha = 10, beta = 4 )

```

---

<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:** [August 8, 2022, 3:21pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/4 "2022-08-08T15:21:55Z")

</div>

> Do some kind of homemade curryfication, where I specialize a preprocesser with its parameters before passing it to `myfunction`.

Why are you disparaging the approach of enforcing that the user-provided function have a specific arrow type (e.g. `(Int, Int) -> Float64)`)? This seems like very normal behavior for higher-order functions.

---

<div class="post-metadata">

**Author:** ![nsquare](https://avatars.discourse-cdn.com/v4/letter/n/779978/32.png) [@nsquare](https://discourse.julialang.org/u/nsquare)\
**Post date:** [August 9, 2022, 10:07am UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/5 "2022-08-09T10:07:23Z")

</div>

Thanks a lot for your answers. Both solutions from Gunnar and Steffen would work in my case. I include below a toy MWE for future reference, and also in case I’m doing something wrong you can maybe comment it. I am not very experienced in Julia.

With Gunnar’s solution:

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function,
                    preprocess_args::Tuple)
    A = preprocess(input, preprocess_args...)
    return A
end

function nonneg(A)
    B = copy(A)
    B[B.<0] .= 0
    return B
end

function addx(A, x)
    return A .+ x
end

a = randn(2,3)
display(a)
a1 = myfunction(a, nonneg, ())
display(a1)
a2 = myfunction(a, addx, (5,))
display(a2)

```

With Steffen’s:

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function;
                    args...)
    A = preprocess(input; args...)
    return A
end

function nonneg(A)
    B = copy(A)
    B[B.<0] .= 0
    return B
end

function addx(A; x)
    return A .+ x
end

a = randn(2,3)
display(a)
a1 = myfunction(a, nonneg)
display(a1)
a2 = myfunction(a, addx, x=5)
display(a2)

```

I think I will use the second solution as the syntax will be clearer in my case.

About jonhmyleswhite’s comment: it would probably be cleaner the way your propose it, but in my case I really need functions that take different number and types of parameters. Maybe my use case is not a good one for higher-order programming (I have no experience at all) but I thought this could help me have less duplicate code.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [August 9, 2022, 3:47pm UTC](https://discourse.julialang.org/t/best-practice-for-passing-parameters-to-functions-passed-as-parameters/85479/6 "2022-08-09T15:47:13Z")

</div>

For the record, this is how a currying approach could look:

```julia
function myfunction(input::AbstractMatrix,
                    preprocess::Function)
    A = preprocess(input)
    return A
end

function nonneg(A)
    B = copy(A)
    B[B.<0] .= 0
    return B
end

function addx(A, x)
    return A .+ x
end

a = randn(2,3)
a1 = myfunction(a, nonneg)
a2 = myfunction(a, x -> addx(x, 5))

```
