macros - Clojure 宏扩展

标签 macros clojure lisp

我正在研究一个宏,我想弄清楚如何避免扩展某些形式,以下面的宏为例,


(defmacro and
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

When expanded,

(mexpand-all '(and 1 2 3))

成为,


(let* [and__973__auto__ 1]
      (if and__973__auto__
        (let* [and__973__auto__ 2]
              (if and__973__auto__ 3 and__973__auto__))
        and__973__auto__))

在这种情况下,我需要做的是阻止 let 扩展为 let*。

最佳答案

嗯?目前尚不清楚“停止” 扩展的意思。 let 是 clojure.core 中定义的宏,编译器对此一无所知:它只理解 let*。如果您的宏扩展为 let(以某种方式)拒绝进一步扩展,它将无法编译。

如果你只想单独检查宏的输出,而不用担心递归扩展它,你应该使用 macroexpandmacroexpand-1 而不是这个 mexpand-all 东西。我不知道 mexpand-all 来自哪里,但是当我需要类似的东西时,我会使用 clojure.walk/macroexpand-all

关于macros - Clojure 宏扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5986383/

相关文章:

lisp - 为什么 CASE 不能用于字符串值而只能用于符号值?

C 错误 : missing whitespace after the macro name

macros - 使用宏创建记录

clojure - 查找 ref-to-many 属性包含所有输入元素的实体

clojure - (启动(刷新)) => 无法设置! : *e from non-binding thread

Lisp - 从另一个对列表中删除一个对列表的实例

emacs - Lisp 源代码文件本身是列表吗?

mysql - 如何在 SQL/Teradata 中创建宏变量?

c - 是否可以定义 const 值并要求用户输入它?

ios - Objective-C 系统宏中的下划线命名约定