On Fri, Aug 5, 2016 at 9:50 PM, Tamas Papp <[email protected]> wrote:

> TL;DR: how to construct an :(a,b,c) expression from [:a,:b,:c] for use
> in a macro.
>

julia> a = [:a, :b, :c]
3-element Array{Symbol,1}:
 :a
 :b
 :c

julia> :($(a...))
(:a,:b,:c)



>
> Long version: I am trying to construct a macro that zips columns of
> dataframes and then iterates & collects over them, eg something that
> expands
>
> @in_dataframe(df, a+b+c, 1 => a, 2 => b, 3 => c)
>
> to
>
> [a+b+c for (a,b,c) in zip(df[1],df[2],df[3])]
>
> Note how indexes are values, not inferred from walking the expression,
> as in DataFramesMeta. However, I want
>
> @in_dataframe(df, a+b+c, a, b, c)
>
> to work when column names correspond to symbols, hence the two
> parse_colspec methods below.
>
> I came up with
>
> macro in_dataframe(df, expression, colspecs...)
>     function parse_colspec(e::Expr)
>         @assert e.head == :(=>)
>         varname = e.args[2]
>         @assert isa(varname, Symbol)
>         (varname,e.args[1])
>     end
>     function parse_colspec(varname::Symbol)
>         (varname,QuoteNode(varname))
>     end
>     dfvar = gensym("df")
>     vars = map(parse_colspec, colspecs)
>     quote
>         let $dfvar = $df
>             [$expression
>              for $(tuple(Symbol[v[1] for v in vars]...)) in
>              zip($([:($dfvar[$(v[2])]) for v in vars]...))]
>         end
>     end
> end
>
> Trying
>
> macroexpand(:(@in_dataframe(df1, a+b+c, 1 => a, 2 => b, 3 => c)))
>
> looks OK, except for the (:a,:b,:c) after the "for". I can't figure out
> how to get (a,b,c). Other hints to improve style would also be
> appreciated.
>
> Regards,
>
> Tamas
>

Reply via email to