I have a function f that has many different versions (e.g. f_A, f_B, f_C, …), “subversions” (e.g. f_Aa, f_Ab, …, f_Ba, f_Bb, …), “subsubversions” (e.g. f_Aaa, …), and so forth. Each of these takes a large number of parameters, most of which they have in common but some they don’t. I want to test the different versions of this function in a loop because there are so many of them. Perhaps something like:
f_A(;x, y, unused...) = x + y
f_B(;x, z, unused...) = x + z
function f(version; kwargs...)
return eval(Expr(:call, Symbol("f_", version), kwargs...))
end
for ver = ["A", "B"]
f(ver, x=1, y=2, z=3) # Throws error
end
It seems that the keyword arguments are passed to the function f_A or f_B as Pairs instead of kw arguments. For example, using range as an example of a built-in function with keyword arguments,
expr1 = Meta.parse("range(1, stop=2, length=5)")
Meta.dump(expr1)
Returns the following:
Expr
head: Symbol call
args: Array{Any}((4,))
1: Symbol range
2: Int64 1
3: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol stop
2: Int64 2
4: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol length
2: Int64 5
Whereas my expression looks like this:
function get_expr(version; kwargs...)
return Expr(:call, Expr(Symbol("f_", version), kwargs...))
end
expr2 = get_expr("A", x=1, y=2, z=3)
Meta.dump(expr2)
Returns:
Expr
head: Symbol call
args: Array{Any}((1,))
1: Expr
head: Symbol f_A
args: Array{Any}((3,))
1: Pair{Symbol,Int64}
first: Symbol x
second: Int64 1
2: Pair{Symbol,Int64}
first: Symbol y
second: Int64 2
3: Pair{Symbol,Int64}
first: Symbol z
second: Int64 3
So how can I get the keyword arguments to be passed to f_A or f_B as Symbol kw instead of Pair{Symbol,Int64}?