Proper way to define functions with additional parameters

Hi, I have the need to define functions that takes arguments and parameters, where the latter often times don’t change for a given scenario (e.g., a physical model with many parameters). I’m doing it in the following way

struct myParamFun
       fun::Function
       param
end
(pf::myParamFun)(x...)=pf.fun(pf.param,x...)

or else

struct myParamFun{P}
       fun::Function
end
(pf::myParamFun{P})(x...) where P =pf.fun(P,x...)

Here param or P may be a struct with many fields.
Are these proper ways to do what I have in mind? If not, what would be a better way of doing it? Hopefully the function should be GPU and / or AD friendly?

Often, this sort of thing is accomplished by constructing an anonymous function that “hides” the extra parameters, for example:

(x, y) -> myfunc(x, y, otherparams…)

which can be done on the fly as needed.

1 Like

This is commonly referred to as partial application. I would recommend not re-inventing the wheel, and instead using Julia’s built-in generic partial application type.

Which it doesn’t have, but it could look like this one day. You will probably need to first wait for the heat death of the universe though.

Until then, you can always create anonymous functions as described above.

1 Like

Thanks for the feedback. I get that there is nothing non “julian” with anonymous functions. However, I did run into broadcast over CuArray problems if the parameters are not explicitly constant, even though they come from an immutable struct, as this post indicates. Wondering if there is a way though …

Using an anonymous function, instead of

pf=myParamFun((x,y,z,v)->x+y-z*v,2)

you’d have

pf=(x...) -> ((x,y,z,v)->x+y-z*v)(x...,2)
1 Like