macros - 在宏中使用来自外部(词法)环境的变量

标签 macros scheme lisp common-lisp

如何让这段宏发挥预期的作用? -- 我想从词法环境中捕获 p 而不必将其作为参数发送给宏。

(define-syntax-rule (fi a b)
    (if p a b)) ;--->capture `p` from lexical env

(let ((p #t))
    (fi 1 2))

奖金谢谢 -- 我如何在 CL 中做同样的事情?

最佳答案

在 Common Lisp 中,宏只是一个函数,它将代码的列表结构作为输入并返回表示新代码的列表结构。

(defmacro fi (a b)
  `(if p ,a ,b))

所以如果你像这样使用 fi:

(let ((p t)) ; Common Lisp uses 't' for truth.
   (fi 1 2))

就好像你输入了:

(let ((p t))
  (if p 1 2))

要了解如何进行此扩展,请将 fi 想象成一个函数,并为其提供参数 1 和 2。

(fi 1 2) => (if p 1 2)

然后获取它返回的列表结构并将其替换为对 fi 的调用。

您给出的示例很简单,因为参数对自身求值。如果你有更复杂的表达式(* 1 1)和(+ 1 1),实际的列表结构被传入(a的值是列表(* 1 1),b的值是列表(+ 1 1))

(fi (* 1 1) (+ 1 1)) => (if p (* 1 1) (+ 1 1))

关于macros - 在宏中使用来自外部(词法)环境的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25576624/

相关文章:

c - 使用 gdb 调试 C 预处理器宏中的崩溃

vba - 错误 450 : Wrong number of arguments or invalid property assignment on vba

我可以使用另一个 #define 指令重新定义宏吗?

parameters - 参数周围没有括号的方案 Lambda 表达式

string - 检查字符串是否只是字母(没有符号和数字)lisp

macros - 如何使用批处理文件打开并运行 Excel 宏

performance - 我可以使用 Scheme 有效地实现快速排序吗?

lisp - 方案: "expects 1 argument, given 4"奇怪的行为

emacs - 如何在 emacs lisp 中硬编码参数?

lisp - 为什么有些人使用 #'(lambda 而不是 (Common Lisp 中的 lambda?