macros - Julia 中的宏调用与宏定义环境

标签 macros julia hygiene

我试图从 macro hygiene 上的 Julia 元编程文档中的声明中弄明白.该文件声称

Julia’s macro expander solves these problems in the following way. First, variables within a macro result are classified as either local or global. A variable is considered local if it is assigned to (and not declared global), declared local, or used as a function argument name. Otherwise, it is considered global. Local variables are then renamed to be unique (using the gensym() function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro’s locals will not conflict with any user variables, and time and println will refer to the standard library definitions.



我写了一个小程序,看看全局变量是否确实在宏定义环境中解析了。我写了以下内容:
f(x) = x + 100 

macro g()         # According to Julia docs, ...
  :(f(x) + 5)     # ... f is global, x is local, right?
end               # if so, f should refer to the f above?

(function main()
  local x = 3
  f(x) = x - 100  # f in the call environment subtracts 100
  println(@g())   # So why does this do -92?
end)()

如果我要正确理解 Julia 文档,宏卫生的一部分是确保在宏的返回表达式中调用的任何函数都不会被调用者环境中的同名函数劫持。但这正是这里发生的事情,函数 f使用的是本地定义的那个。

我原以为我必须使用 esc为了使用 f在调用点的范围内。但事实并非如此,为什么呢?

此外,我注意到变量 x宏内部的结果被认为是局部的,所以应该为它生成一个新的 gensymed 变量名,以免与 x 冲突。在宏调用环境中。但这也没有发生!

我如何阅读文档以了解 esc 的原因这里不需要用吗?

编辑(澄清)
  • 当我 claim 时 f是全局性的和 x是本地的,根据文档,我这样做是因为我看到 x用作函数参数。我明白 x没有被写入也没有被声明为本地的,它当然看起来是全局的,但是那些文档声称函数参数也应该是全局的!
  • 我知道卫生的常见部分,其中局部变量的 gensymming 确保宏调用者上下文中的同名变量不会被无意中粘贴。但是,文档声称对于函数,在宏定义的上下文中看到的函数受到保护,不受调用者使用它们自己的影响。这是对我来说毫无意义的部分,因为我的实验表明并非如此。
  • 最佳答案

    这是一个错误。这是 Julia 0.5 及更早版本的旧问题,已在 Julia 0.6 中修复。见 https://github.com/JuliaLang/julia/issues/4873想要查询更多的信息。

    关于macros - Julia 中的宏调用与宏定义环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33989020/

    相关文章:

    通过预处理器宏实现小差异的 C 代码重复

    java - openJDK 版本号 - 这些是宏吗? : $MAJOR. $次要.$安全。如何访问这些内容?

    c - 使用可变宏动态地为宏名称添加前缀

    dataframe - 在Julia DataFrames中测试NA的正确方法

    julia - 向量数组的条件赋值语法

    macros - Scheme 语法规则 - (let) 和 (define) 之间变量绑定(bind)的区别

    行为类似于 __COUNTER__ 宏的 C++ 结构

    julia - @printf 宏使用预定义的格式字符串产生错误

    macros - Racket 中的宏定义宏?