Problem with escaping anonymous function expressions and let blocks


#1

Consider a macro like:

manipulate_expr(expr) = esc(expr)
macro test(expr)
    Expr(expr.head, esc(expr.args[1]), manipulate_expr.(expr.args[2:end])...)
end

manipulate_expr is a placeholder for a transformation of the AST. This definition works for most types of expressions I tried, e.g.:

julia> @macroexpand @test x = 1
:(x = 1)

However, I can’t find a way to manipulate the right hand side of an anonymous function:

julia> @macroexpand @test x -> x
:($(Expr(:error, "\"(escape x)\" is not a valid function argument name")))

A similar problem occurs for let blocks:

julia> @test let x = 1; x end
ERROR: syntax: invalid let syntax

How can I apply an AST transformation to these expressions?
(For an example use case, see, e.g., https://github.com/ti-s/ShowEach.jl)


#2

It’s this issue. The only work-around I know is to esc the whole expression (i.e. esc(Expr(...)))


#3

Ok, then I will use obscure names for the functions that are inserted to make escaping the whole expressions safe.


#4

Or you can use gensym