DataFramesMeta’s macros are weird, because they want to behave like functions. @transform(df, y = 5)
, but they are still macros.
If @transform
were a function, it would be implemented like transform(df; kwargs...)
. Indeed, this is how the functions that @transform
calls work.
So I thought, in DataFramesMeta #117. So I thought that it would be nice to have pairs
of keyword arguments work in @transform
as well so you could get run-time keyword argument evaluation @transform(df; x => mean(:x1)
as well.
It turns out this isn’t so easy, and definitions like macro foo(args...; kwars...)
are disallowed. This is understandable, since macros work with Expr
and therefor keyword arguments dont really make sense.
No big deal, one can just inspect the AST inputted into a macro call and make pair
s of keyword arguments just work, right? This is where unexpected behavior comes in.
macro foo(args...)
dump(ars)
end
Returns
julia> @foo(a = 1; b = 2)
Tuple{Expr,Expr}
1: Expr
head: Symbol parameters
args: Array{Any}((1,))
1: Expr
head: Symbol kw
args: Array{Any}((2,))
1: Symbol b
2: Int64 2
2: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol a
2: Int64 1
However
macro bar(x, args...)
dump(args)
end
returns
julia> @bar(x, a = 1; b = 2)
Tuple{Symbol,Expr}
1: Symbol x
2: Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol a
2: Int64 1
When you have a macro where everything is splatted, the collected expression includes everything between the parentheses. But when you have a multi-argument macro, where the second argument is splatted, the collected expression only goes until the first semi-colon.
This seems like unexpected and inconsistent behavior. Should I file an issue?
Seems to be some discussion of similar behavior here in MacroTools.jl.