gpt4 book ai didi

macros - Common Lisp 宏中的词法绑定(bind)

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:40 24 4
gpt4 key购买 nike

我目前正在研究 Graham 的 On Lisp,发现这一点特别难以理解:

Binding. Lexical variables must appear directly in the source code. The first argument to setq is not evaluated, for example, so anything built on setq must be a macro which expands into a setq, rather than a function which calls it. Likewise for operators like let, whose arguments are to appear as parameters in a lambda expression, for macros like do which expand into lets, and so on. Any new operator which is to alter the lexical bindings of its arguments must be written as a macro.

这来自第 8 章,该章描述了何时应该和不应该使用宏来代替函数。

这段话他到底是什么意思?有人可以举一两个具体的例子吗?

非常感谢!

最佳答案

setq 是一种特殊形式,不会计算其第一个参数。因此,如果你想制作一个更新某些东西的宏,你不能这样做:

(defun update (what with)
(setq what with))

(defparameter *test* 10)
(update *test* 20) ; what does it do?
*test* ; ==> 10

所以在函数update setq 中更新变量what20,但是它是一个局部变量具有更新值 10 的变量,而不是 *test* 本身。为了更新 *test* setq 必须将 *test* 作为第一个参数。一个宏可以做到这一点:

(defmacro update (what with)
`(setq ,what ,with))

(update *test* 20) ; what does it do?
*test* ; ==> 20

您可以准确地看到宏展开的结果代码:

(macroexpand-1 '(update *test* 20))
; ==> (setq *test* 20) ; t

类似的例子。您不能使用函数模仿 ifcond:

(defun my-if (test then else)
(cond (test then)
(t else)))

(defun fib (n)
(my-if (< 2 n)
n
(+ (fib (- n 1)) (fib (- n 2)))))

(fib 3)

无论您传递什么参数,您都会得到一个无限循环,该循环总是调用递归情况,因为所有my-if 参数总是被求值。使用 condiftest 进行评估,并基于此 thenelse 被评估,但从来没有无条件地评估。

关于macros - Common Lisp 宏中的词法绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49245008/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com