为什么变量可以在 Julia 宏名称修饰中以 # 开头?

Why Can Variables Start With # In Julia Macro Name Mangling?

我只是在学习宏,我对变量名如何以 # 开头感到困惑,但这正是宏似乎成功完成的事情。例如,如果我想将一个变量设置为等于 4:

macro testMacro(sym)
  esym = esc(sym)
  quote
    temp = 4
    $esym = temp
    return
  end
end

然后

julia> macroexpand(:(@testMacro α))
quote  # none, line 4:
    #132#temp = 4 # line 5:
    α = #132#temp # line 6:
    return
end

julia> @testMacro α

julia> α
4

请注意,临时变量名为#132#temp,据我所知,它会在 REPL 中像那样被计算。然而,这似乎是不可能的,因为从技术上讲,整行现在应该是一条评论。

如果我查看宏中的第一个表达式,我会得到无法重现的内容。

julia> macroexpand(:(@testMacro α)).args[2]
:(#132#temp = 4)

julia> ex = :(#132#temp = 4)


ERROR: syntax: incomplete: premature end of input

这是怎么回事?我想我基本上有两个问题。 1.) 如果可能的话,我如何定义一个以#开头的变量(即使在表达式中)? 2.) 假设存在这样一个变量,julia 是如何做到不把它当作注释的?

What's going on here?

此处的名称修改是为了保留 macro hygiene 以便在宏中定义的名称不会与环境中的其他名称冲突。 (可以使用 esc 覆盖它)

1.) If it's possible, how can I define a variable (even within an expression) that starts with a #?

我不确定您为什么要这样做,因为访问变量会很麻烦。但有可能:

julia> eval(Expr(:(=), symbol("#s"), 1))
1

julia> whos()
#s                            Int64
Base                          Module
Core                          Module
LastMain                      Module
Main                          Module
ans                           Int64

julia> eval(symbol("#s"))
1

2.) Assuming the existence of such a variable, how does julia manage to not treat it as a comment?

注释在解析器级别被删除,因此系统的其余部分永远不会真正看到它们。如上所示,可以从包含 # 的任意字符串创建 Symbol,这就是宏代码在内部所做的事情。