Looking for a curry package

I have a lot of functions that I would like to add an extra method to with the code

f(; kwargs...) = (args...; kw...) -> f(args...; kwargs..., kw...)

where f is the function which takes at least one positional argument and one keyword argument. Is there a package that can do this?

I made a macro that more or less solves my needs:

macro flexkw(f, g=f)
    :($f(; kwargs...) = (args...; kw...) -> $g(args...; kwargs..., kw...))
end

This allows me to just run

@flexkw f

to add the new method to the function f. If a package that can do this already exists, then I would still be interested in hearing about it.

Should humour be allowed here, you might want to consider this package.

3 Likes

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?

f(a, b; negative=false, exponent=2) = negative ? (a - b)^exponent : (a + b)^exponent
f_negative(args...; kwargs...) = f(args...; negative=true, kwargs...)

@assert f(1, 2; exponent=3) == 27
@assert f(1, 2; negative=true, exponent=3) == -1
@assert f_negative(1, 2; exponent=3) == -1

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).


@rafael.guerra : I like the humour :grinning_face_with_smiling_eyes:

1 Like