检查defmacro(clojure)中的符号相等性



这将返回false

(defmacro scratch [pattern]
`(= 'b (first ~pattern)))
(scratch '(b))

但是,下面的输出是b

(defmacro scratch2 [pattern]
`(first ~pattern))
(scratch2 '(b))

如何设置第一个宏以返回true

这是正在发生的,因为您在宏中引入的'b是按名称命名的:

示例:

user> (defmacro nsmac []
`(namespace 'b))
user> (nsmac)
;;=> "user"

而你传递的值不是:

user> (namespace (first '(b)))
;;=> nil

因此,您可以将带名称空间的符号传递给宏,如下所示:

user> (scratch '(user/b)) 
;;=> true

或者你可以修复你的宏使用未命名的符号(已知的qoute取消引号的技巧(:

(defmacro scratch [pattern]
`(= '~'b (first ~pattern)))
user> (scratch '(b)) 
;;=> true

但你真正想要的是,在编译时检查这个,因为这个宏作为一个普通函数更好,因为它没有使用任何与宏相关的优点。

它可能看起来像这样:

(defmacro scratch [pattern]
(= 'b (first pattern)))
(scratch (b))
;;=> true

关于名称空间的一些内容可以在本文中找到

最新更新