I did it! The macro I sought was:
macro newrule(expr)
quote $(Expr(:quote, expr)) end
end
Now we have, as desired:
julia> [@newrule $op(a, 0) => a for op ∈ (+, -)]
2-element Array{Expr,1}:
:((+)(a, 0) => a)
:((-)(a, 0) => a)
QuoteNode(expr) was a red herring. I thought this played the role of Expr(:quote, expr), but it does not, and I wasn’t exactly sure what QuoteNode was meant for until I read this issue.