在 defmacro (clojure) 中检查符号相等性
checking symbol equality in defmacro (clojure)
这 returns false
.
(defmacro scratch [pattern]
`(= 'b (first ~pattern)))
(scratch '(b))
然而,下面的输出是b
。
(defmacro scratch2 [pattern]
`(first ~pattern))
(scratch2 '(b))
如何将第一个宏设置为 return true
?
这正在发生,因为您在宏中引入的 'b 是命名空间的:
示例:
user> (defmacro nsmac []
`(namespace 'b))
user> (nsmac)
;;=> "user"
而您传递的值不是:
user> (namespace (first '(b)))
;;=> nil
因此,您可以将命名空间符号传递给宏,如下所示:
user> (scratch '(user/b))
;;=> true
或者您可以修复您的宏以使用未命名空间的符号(qoute-unquote 的已知技巧):
(defmacro scratch [pattern]
`(= '~'b (first ~pattern)))
user> (scratch '(b))
;;=> true
但您真正想要的是检查 compile-time 中的这个宏,因为您拥有的这个宏作为普通函数更好,因为它没有使用任何 macro-related 优点。
它可能看起来像这样:
(defmacro scratch [pattern]
(= 'b (first pattern)))
(scratch (b))
;;=> true
可以找到有关命名空间的信息in this article
这 returns false
.
(defmacro scratch [pattern]
`(= 'b (first ~pattern)))
(scratch '(b))
然而,下面的输出是b
。
(defmacro scratch2 [pattern]
`(first ~pattern))
(scratch2 '(b))
如何将第一个宏设置为 return true
?
这正在发生,因为您在宏中引入的 'b 是命名空间的:
示例:
user> (defmacro nsmac []
`(namespace 'b))
user> (nsmac)
;;=> "user"
而您传递的值不是:
user> (namespace (first '(b)))
;;=> nil
因此,您可以将命名空间符号传递给宏,如下所示:
user> (scratch '(user/b))
;;=> true
或者您可以修复您的宏以使用未命名空间的符号(qoute-unquote 的已知技巧):
(defmacro scratch [pattern]
`(= '~'b (first ~pattern)))
user> (scratch '(b))
;;=> true
但您真正想要的是检查 compile-time 中的这个宏,因为您拥有的这个宏作为普通函数更好,因为它没有使用任何 macro-related 优点。
它可能看起来像这样:
(defmacro scratch [pattern]
(= 'b (first pattern)))
(scratch (b))
;;=> true
可以找到有关命名空间的信息in this article