Figuring out behaviour of expression interpolation

I have a simple function that generates code, for a generated function I want to make:

function issite_gen(operation, N)
    ex = :($operation(arr[1]))
    for i in 2:N
        ex = :($ex | $operation(arr[$i]))
    end
    ex
end

It does things like this:

julia> issite_gen(:count_ones, 1)
:(count_ones(arr[1]))

julia> issite_gen(:count_ones, 2)
:(count_ones(arr[1]) | count_ones(arr[2]))

julia> issite_gen(:count_ones, 3)
:((count_ones(arr[1]) | count_ones(arr[2])) | count_ones(arr[3]))

I wanted to see if I could change the | operator using a parameter e.g, make it a + insteadof |, but it messes up the expression generated:

function issite_gen(operation, N, op)
    ex = :($operation(arr[1]))
    for i in 2:N
        ex = :($ex $op $operation(arr[$i]))
    end
    ex
end

julia> issite_gen(:count_ones, 1, :+)
:(count_ones(arr[1]))

julia> issite_gen(:count_ones, 2, :+)
:((count_ones(arr[1]) $ op) $ operation(arr[2]))

julia> issite_gen(:count_ones, 3, :+)
:((((count_ones(arr[1]) $ op) $ operation(arr[2])) $ op) $ operation(arr[3]))

Does anybody know what the issue is I’m missing?

You cannot splice an operator, use the call syntax since it’s just a function call. :($op($ex, $....)). In general, the parse cannot figure out that you want an operator there so it parses it as chains of $ operators.

Ahh ok, thanks @yuyichao, I will try this out when I get home from work!

@yuyichao I just had a thought: I don’t suppose you know if unrolling during compile time is better than using the new dot syntax followed by a use of “reduce”? If that syntax essentially does this for me then there’s no point in me re-implementing a similar thing.