Is there a function that can take any kwargs function and return the same function with a varargs… parameter? That is
convert
f(; a ) = 1
to
f(; a, X... ) = 1
and
f(; a,b,c ) = a+b+c
to
f(; a,b,c, X... ) = a+b+c
Is there a function that can take any kwargs function and return the same function with a varargs… parameter? That is
convert
f(; a ) = 1
to
f(; a, X... ) = 1
and
f(; a,b,c ) = a+b+c
to
f(; a,b,c, X... ) = a+b+c
That’s a job for a macro. First see how the function expressions look without and with a varargs argument.
julia> dump(:(f(; a) = 1))
Expr
head: Symbol =
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol f
2: Expr
head: Symbol parameters
args: Array{Any}((1,))
1: Symbol a
2: Expr
head: Symbol block
args: Array{Any}((2,))
1: LineNumberNode
line: Int64 1
file: Symbol REPL[1]
2: Int64 1
julia> dump(:(f(; a, _...) = 1))
Expr
head: Symbol =
args: Array{Any}((2,))
1: Expr
head: Symbol call
args: Array{Any}((2,))
1: Symbol f
2: Expr
head: Symbol parameters
args: Array{Any}((2,))
1: Symbol a
2: Expr # Here is the vararg.
head: Symbol ...
args: Array{Any}((1,))
1: Symbol _
2: Expr
head: Symbol block
args: Array{Any}((2,))
1: LineNumberNode
line: Int64 1
file: Symbol REPL[2]
2: Int64 1
Now we need to transform the former to the latter.
macro ignore_extra_kwargs(ex)
push!(ex.args[1].args[2].args, :(_...))
return esc(ex)
end
Here it is in action:
julia> @macroexpand @ignore_extra_kwargs f(; a ) = 1
:(f(; a, _...) = begin
#= REPL[4]:1 =#
1
end)
julia> @ignore_extra_kwargs f(; a ) = 1
f (generic function with 1 method)
julia> f(a = 1, b = 2)
1
Sorry to be stupid. How come this doesn’t work?
f(; a ) = 1
@ignore_extra_kwargs f
The macro transforms the code which defines f
, it doesn’t act on the function.