Search code examples
functionpackagejuliametaprogramming

Julia - Using metaprogramming to define several functions


I'm developing a package in Julia, and in my package I have several functions that have the same layout, but some small variations in terms of the parameters they use. For example:

function MyFunction1(arg1, arg2)
  do(arg1,arg2,parameter1)
end

function MyFunction2(arg1, arg2)
  do(arg1,arg2,parameter2)
end

function MyFunction3(arg1, arg2)
  do(arg1,arg2,parameter3)
end

Now, what I'd like to do was creating one specification array, where I pass the functions names and the parameters, and use metaprogramming to define this functions, for example:

spec = [["MyFunction1","parameter1"],["MyFunction2","parameter2"],["MyFunction3","parameter3"]]

How can one do this in Julia? Note that this is a simplified example, and I actually want to allow for more complex variation, otherwise it would be wiser to just create one function with the additional parameters instead of creating several functions.


Solution

  • You should consider not using metaprogramming at all here and instead defining a general function like this:

    function my_general_function(arg1, arg2, parameters)
       do(arg1, arg2, parameters)
    end
    

    Then you can define each variant in one line:

    my_function_1(arg1, arg2) = my_general_function(arg1, arg2, parameters1)
    my_function_2(arg1, arg2) = my_general_function(arg1, arg2, parameters2)
    my_function_3(arg1, arg2) = my_general_function(arg1, arg2, parameters3)
    

    If the arg1, arg2 part is sufficiently annoying to write out, you could write a function generator like this:

    function my_function_generator(parameters)
       (arg1, arg2) -> do(arg1, arg2, parameters)
    end
    

    Then you define each specialized version like this:

    const my_function_1 = my_function_generator(parameters1)
    const my_function_2 = my_function_generator(parameters2)
    const my_function_3 = my_function_generator(parameters3)
    

    This could be done with macros, but there's no need for them here and things are generally simpler and clearer if you stick with higher order functions (functions that take functions as arguments or return functions) rather than macros when possible.