# Calling functions with arbitrary combination of given argument names inside other functions

For ease of use and readability in a program that I’m writing, I would like users to be able to define functions with any combination (and if possible order) of a fixed set of symbols, say `{a,b,c,d}`. This function needs to be able to be called in another function that is part of some algorithm. The symbol names have inherent meaning within the algorithm. As an example I might have a function that depends on any of three cartesian coordinates `{x,y,z}` of a grid.

I’m not sure how I would deal with the fact that the algorithm doesn’t know how many and which of the arguments the function will take. I know how to extract the argument names as symbols, so in principle I could write a a lot of if statements for all combinations of the arguments, but this obviously a very inelegant and cumbersome option. I might also want to expand the set of allowed symbols later on, so the amount of combinations might get very big…

Another solution would be to always define any of the functions with all of the argument names. This is not great for readability, however, since it would be very nice to see from just the function, on which of the arguments it depends.

Is there a good way to do this, or is this just bad practice?

You can do something like this:

``````julia> my_invoke(f, a, b, c, d) = f(;a, b, c, d)
my_invoke (generic function with 1 method)

julia> f1(;a, c, _...) = a + c
f1 (generic function with 1 method)

julia> f2(;d, b, a, _...) = a * b * d
f2 (generic function with 1 method)

julia> my_invoke(f1, 1, 2, 3, 4)
4

julia> my_invoke(f2, 1, 2, 3, 4)
8
``````

The overhead is that your users must make their functions keyword arguments only with the leading `;` and discard unneeded arguments with the trailing `, _...`. If this is too annoying you could instead provide a macro that rewrites their function definition in this form. I.e. they would have to write something like

``````@frobricate f1(a, c) = a + c
``````

and the macro would rewrite it to the earlier `f1` definition.

1 Like