gpt4 book ai didi

common-lisp - 为什么这个来自 ANSI Common Lisp 的作用域示例不能按预期工作?

转载 作者:行者123 更新时间:2023-12-01 22:04:07 25 4
gpt4 key购买 nike

我是 Lisp 新手,正在阅读 Paul Graham 的 ANSI Common Lisp,练习之一是定义一个像 apply 这样的函数,其中之前打印出任何数字它返回的值默认以八进制打印。

我尝试了以下方法:

(let ((*print-base* 8))
(defun like-apply (&rest args)
(apply #'apply args)))

但它没有按预期工作:

(like-apply #'princ '(8)); returns 8 8 (expecting 10 8)

但是以下方法有效:

(defun apply8 (&rest args)
(let ((*print-base* 8))
(apply #'apply args)))

正确返回:

(apply8 #'princ '(8)); returns 10 8 (as expected)

所以我的问题是为什么第二个示例有效,但第一个示例无效?两者似乎都操纵 *print-base* 变量。

最佳答案

Common Lisp 使用 let 来绑定(bind)词法变量和“特殊”(动态)变量。您期望的行为是词汇性的,而您观察到的行为是动态的。打印机变量都很特殊,因此让我们为它们创建一个动态绑定(bind)。

打印机变量有时会在动态绑定(bind)有用的示例中使用。例如,您可以通过绑定(bind) *print-base* 来控制 princ 的行为,这一事实是通过动态绑定(bind)启用的,否则 princ 会在定义 princ 时引用 *print-base* active 的绑定(bind)。

这种行为是许多 Common Lisp 程序员坚持特殊变量的 *earmuffs* 命名约定的主要原因。请注意,defvar 和 defparameter 都创建特殊变量。

关于common-lisp - 为什么这个来自 ANSI Common Lisp 的作用域示例不能按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17904739/

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