在 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