gpt4 book ai didi

lisp - Lisp 中的反引号扩展

转载 作者:行者123 更新时间:2023-12-04 22:34:20 26 4
gpt4 key购买 nike

我是 Lisp 初学者,我很难理解为什么下面的代码会给我一个错误。

(dolist (elem '(mapcar
mapcon))
(when (fboundp `',elem) (print "hello")))

谢谢。

编辑:更多背景信息。我在 Elisp 中写了以下内容,但我不知道如何修复它。

(dolist (ui-elem '(menu-bar-mode
tool-bar-mode
tooltip-mode
scroll-bar-mode
horizontal-scroll-bar-mode))
(when (fboundp `',ui-elem) (ui-elem -1)))

最佳答案

注意

在您的问题中,您混合了 common-lispelisp,但它们是两种不同的语言。然而,这个问题涉及两种语言中相同的概念。

需要引用符号

您要编写的代码会检查符号是否绑定(bind)到函数。您可能已经知道,您可以对符号调用 fboundp 来确定这一点:

(fboundp 'menu-bar-mode)
=> t

当您评估上述形式时,'menu-bar-mode(quote menu-bar-mode) 相同,并且已评估 作为符号对象菜单栏模式。这是作为 fboundp 参数给出的值。

在您的示例中,您想要迭代符号列表,对其调用 fboundp 并在符号表示函数时调用该函数。您可以按如下方式执行此操作:

(dolist (s '(menu-bar-mode and other symbols))
(when (fboundp s)
(funcall s -1)))

符号列表'(菜单栏模式和其他符号)被引用,这意味着当dolist对其求值时,它会看到一个符号列表。在循环的每次迭代中 s 绑定(bind)的值是一个符号对象,不需要引用它们。

在代码中编写符号时必须引用符号,这样它们就不会被解释为变量。当您迭代符号列表时,您已经操作了符号。

另请注意,Common Lisp 和 Emacs Lisp 都是“Lisp-2”,这意味着您必须使用 (funcall ui-elem -1) 而不是编写 (ui-elem -1)。当您编写后一种形式时,这意味着调用字面名为 ui-elem 的函数,因为对于函数应用程序,不会计算列表中的第一个符号,而是按字面意思获取。

引用级别过多

执行您的代码时出现的实际错误是:

(wrong-type-argument symbolp 'mapcar)

它可能看起来像'mapcar表示一个符号,因为当希望解释器评估某些代码作为符号时,您需要引用它。然而,Lisp 打印机以可以为“相似”对象的方式写入对象。如果我希望符号是数字,则打印的错误消息如下,其中符号 foo 打印时不加引号:

(+ 'foo 3)

;; error: (wrong-type-argument number-or-marker-p foo)

在您的错误消息中,您尝试用作符号的形式是(quote mapcar)。回想一下,当您直接调用 fboundp 时:

(fboundp 'mapcar)

这和你写的一样:

(fboundp (quote mapcar))

首先,(quote mapcar) 被求值,作为符号 mapcar。然后,fboundp 应用于该值。

但是当您编写以下内容时,而 ui-elem 绑定(bind)到符号 mapcar:

(fboundp `',ui-elem)

这相当于:

(fboundp `(quote ,ui-elem))

fboundp 的参数评估(quote mapcar)。您还有一层额外的引用。你可以这样写:

(fboundp `,ui-elem)

但是,你不需要使用反引号/逗号,你可以直接写:

(fboundp ui-elem)

关于lisp - Lisp 中的反引号扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68995115/

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