Hi. I’m having trouble defining a macro which manipulates expressions containing `$`

’s. It’s best illustrated by example:

Is it possible to define a macro `@newrule`

such that

```
for op ∈ (+, -)
@newrule $op(a, 0) => a
end
```

expands to a function call `newrule(::Expr)`

```
for op ∈ (+, -)
newrule(:($op(a, 0) => a))
end
```

where `op`

is in the local scope? So at run-time this is should be equivalent to:

```
newrule(:(a + 0 => a))
newrule(:(a - 0 => a))
```

It seems like this should certainly be possible, since the macro performs a purely syntactical transformation at parse-time—but here’s my trouble:

If we do

```
using MacroTools: postwalk
macro newrule(expr)
escaped = postwalk(expr) do node
if node isa Expr && node.head == :$
esc(node.args[1])
else
node
end
end
escaped
end
```

then the macro call `@newrule $op(a, 0) => a`

will return *and evaluate* the expression `:( a + 0 => a )`

, which errors since `a`

is undefined. But we want the macro to return an expression *which evaluates to the expression*, so that the run-time value is the expression `:( a + 0 => a )`

. If I do

```
...
end
QuoteNode(escaped)
end
```

then the macro call results in a run-time expression, but the interpolation is quoted also, so that the run-time value is `:(($(Expr(:escape, :op)))(a, 0))`

.

Thanks for your help!