On Sun, Sep 25, 2016 at 1:09 PM, Jamie Brandon <ja...@scattered-thoughts.net> wrote: > 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).
And by split into multiple lines I mean pulling out common parts. There's no need to call `Symbol` that many times, you can simply do `keys_names = [Symbol("keys_", i) for i in 1:n]` or `keys_names = [gensym() for i in 1:n]` and use `keys_names[i]` everywhere. There's also no need to use `key_$i`, simply `key` should be enough. > > 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. > >