Rather than a macro that defines a function that itself returns an anonymous function that calls the method you want, does it fit in your use case to simply define a method with a different name?
Thanks for the reply; the anonymous function aspect is really important for me because I am using it as input to another function and want to try out several different combinations of keyword values.
e.g. if @flexkw f was run immediately after definition of the f that you define, then
a = sort(rand(55); lt=f(; negative=true, exponent=5))
b = sort(rand(55); lt=f(; exponent=4))
c = sort(rand(55); lt=f(; negative=true, exponent=8))
would be legal and (in my opinion) easier to read than
a = sort(rand(55); lt=(x,y)->f(x,y; negative=true, exponent=5))
b = sort(rand(55); lt=(x,y)->f(x,y; exponent=4))
c = sort(rand(55); lt=(x,y)->f(x,y; negative=true, exponent=8))
For 1 argument functions, this also makes the |> syntax neater:
g(x; a=11, b=7) = a*x + b
@flexkw g
rand(88) |> sort |> g(; a=5, b=8)
# rather than
rand(88) |> sort |> x->g(x; a=5, b=8)
PartialFunctions.jl can produce anonymous functions, but I prefer the solution that I have shown in this post. It is also the solution used by some functions in Base (e.g. contains).
Thanks for bringing this to my attention. For my specific situation I still prefer the @flexkw macro because it is shorter and easier for me personally to read. In a slightly different scenario (where I donât own the function), e.g.
rand(88) |> x->sort(x; rev=true) #1
the FixKw version would be
rand(88) |> FixKw(sort; rev=true) #2
and would be up against
using PartialFunctions
rand(88) |> sort $ (; rev=true) #3
using PartialFuns
@underscores rand(88) |> sort(_; rev=true) #4
The main alternative is to write an eval loop like
for f in functions_to_curry
@eval $f(; kwargs...) = (args...; kw...) -> $f(args...; kwargs..., kw...)
end
where functions_to_curry is a collection of symbols.
Compared to the macro approach itâs mostly a stylistic choice but it might be nicer if you have many functions and can construct functions_to_curry efficiently, e.g. extract all functions from a module.
To make @flexkw work in all situations, one should probably wrap the variables f and g in esc. (Alternatively, one could wrap the whole expression in this case.)
The main issue with macro solutions here is that you have to have know you want to curry before you start typing, since macros look forward at the expression ahead of them for what to transform. I posted a feature request a few years ago for âbackwards-lookingâ macros which would make it easier to do things like x %>% fun(z = 2) (or whatever syntax). But I donât think itâs easily implemented currently.