将符号解析为宏与函数参数的规则是什么?

时间:2012-08-16 13:17:25

标签: variables clojure macros shadowing

我很惊讶地发现alpha-conversion在Clojure中并不安全:

Clojure> ((fn [o] (o 3 2)) +)
5

Clojure> ((fn [or] (or 3 2)) +)
3

Clojure> ((fn [def] (def 3 2)) +)
java.lang.RuntimeException: First argument to def must be a Symbol

(我预计所有三个片段都要评估为5)。

当涉及阴影和宏以及特殊形式时,符号解析的规则是什么?

我正在使用Try Clojure上的版本。

2 个答案:

答案 0 :(得分:6)

根据the documentation

,您无法隐藏特殊表格
  

符号已解决:

     
      
  • 如果它是名称空间限定的,则该值是由符号命名的全局变量的绑定值。如果有的话,这是一个错误   不是由符号命名的全局var,或者引用是否为a   不同命名空间中的非公共var。
  •   
  • 如果它是包限定的,则值是由符号命名的Java类。如果没有符号命名的类,则会出错。
  •   
  • **否则,它不合格,并且以下第一项适用:      
        
    1. 如果它命名为特殊表格,则视为特殊表格,必须相应使用。**
    2.   
    3. 在当前命名空间中完成查找,以查看是否存在从符号到类的映射。如果是,则考虑符号   命名一个Java类对象。请注意,类名通常表示类   物体,但特殊处理的特殊形式,例如''   和新的。
    4.   
    5. 如果在本地范围内(即在函数定义中),则进行查找以查看它是否命名本地绑定(例如函数参数)   或者让自己的名字)。如果是,则该值是本地的值   结合。
    6.   
    7. 在当前命名空间中完成查找,以查看是否存在从符号到var的映射。如果是,则该值是该值   绑定由符号引用的var。
    8.   
    9. 这是一个错误。
    10.   
  •   

而且我不确定,但是我将这一段(从同一页面)解释为意味着你不能影响宏:

  

宏是操纵表单的函数,允许语法   抽象。如果呼叫的运营商是命名全局的符号   var是一个宏函数,调用宏函数并且是   通过了未评估的操作数表格。宏的返回值是   然后在其位置进行评估。

     

如果运营商不是特殊表格或宏,则会考虑通话   一个函数调用。

答案 1 :(得分:3)

前两个对我来说都评价为5(Eclipse中的Clojure 1.4 /逆时针REPL)。如果你得到3,我怀疑Try Clojure中有一个错误。

你应该能够在本地影响函数和宏名称(虽然它通常不是一个好主意,因为它可能导致一些微妙和令人困惑的错误!)。

第三个不起作用,因为defspecial form。特殊形式从Clojure阅读器和/或编译器获得特殊处理,因此您无法遮蔽它们。