Here is some code I just wrote this evening: n = length(T.parameters) index_types = typeof_index(T.parameters) pushes = map(1:n) do i :(push!(columns[$i], $(Symbol("key_$i")))) end body = quote $(pushes...) end for i in n:-1:1 body = quote $(Symbol("keys_$i")) = collect(keys($(Symbol("index_$i")))) sort!($(Symbol("keys_$i"))) foreach($(Symbol("keys_$i"))) do $(Symbol("key_$i")) $(Symbol("index_$(i+1)")) = $(Symbol("index_$i"))[$(Symbol("key_$i"))] $body end end end quote columns = tuple($([:(Vector{$(T.parameters[i])}()) for i in 1:n]...)) index_1 = relation.unique $body columns end
It's split into multiple lines and there's only one comprehension, but it's still pretty hard to read and debug. (For example, the first time I ran it I got 'syntax: missing comma or ) in argument list' with no line number and hand to check each line by hand). Maybe I could improve the suffixes by writing a macro like: ip1 = i+1 body = @suffix quote keys_i = collect(keys(index_i)) sort!(keys_i) foreach(keys_i) do key_i index_ip1 = index_1[key_i] $body end end The macros in Base.Cartesian almost solve the comprehension problem too, if I make a version that can take arbitrary iters rather than just a number... On 25 September 2016 at 18:53, Yichao Yu <yyc1...@gmail.com> wrote: > On Sun, Sep 25, 2016 at 12:39 PM, Jamie Brandon > <ja...@scattered-thoughts.net> wrote: > > I'm doing a lot of code-generation. There are two patterns that come up > all > > over the place - adding a suffix to a symbol and interpolating from an > array > > comprehension. This is pretty verbose even in the simplest case: > > > > quote > > ... > > row = tuple($([:($(Symbol("val_$ix))) for ix in order]...)) > > ... > > end > > > > I spent a fair amount of time tracking down off-by-1-paren typos that > don't > > show up until the code is run and behaves weirdly eg > $(Symbol("foo_$ix()")) > > vs $(Symbol("foo_$x")()) vs $(Symbol("foo_$x"))() > > > > Is there a better way of handling this? > > Split the code into multiple lines. >