Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia - How to pass kwargs from a function to a macro

You can define a function to pass its keyword arguments to inner functions like this:

function example(data;xcol,ycol,kwargs...)
    DoSomething(; spec=:EX, x=xcol, y=ycol, kwargs...)
end

Now, the function DoSomething accepts many arguments, such as color. This works for functions, but I'd like to do this with a macro from VegaLite.jl:

function example(data;xcol,ycol,kwargs...)
    @vlplot(data=data,mark=:point, x=xcol, y=ycol,kwargs...)
end
example(df,xcol=:Miles_per_Gallon, ycol=:Horsepower, color=:Origin)

Note that the code above does not work.

like image 787
Davi Barreira Avatar asked Nov 09 '20 19:11

Davi Barreira


2 Answers

So the answer here is... it's tricky. And in fact, in general, this isn't possible unless the macro itself supports it.

See, macros do their transformations at parse time — and often will exploit what you've actually written to mean something different and special. For example, @vlplot will specially handle and support JSON-like {} syntaxes. These aren't valid Julia code and can't be passed to a function you define (like example)!

Now, it's tempting to see this and think, ok, let's make that outer example thing into a macro, too! But it's not that easy. I'm not sure it's possible to have a general answer that will always pass the arguments appropriately and get the hygiene correct. I'm pretty sure you need to know something about how the macro you're calling handles its arguments.

like image 94
mbauman Avatar answered Sep 18 '22 23:09

mbauman


you need to add ; before kwargs to signal they are kwargs not positional arguments e.g.:

DoSomething(;spec=:EX, x=xcol, y=ycol, kwargs...)

(this is the answer for DoSomething being a function as this was the original formulation of the question)

like image 44
Bogumił Kamiński Avatar answered Sep 21 '22 23:09

Bogumił Kamiński