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 <[email protected]> wrote:
> On Sun, Sep 25, 2016 at 12:39 PM, Jamie Brandon
> <[email protected]> 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.
>