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

Reply via email to