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.
>

Reply via email to