在 Common Lisp 中使用 iterate 包的正确方法

Posted

技术标签:

【中文标题】在 Common Lisp 中使用 iterate 包的正确方法【英文标题】:Correct way to use the iterate package in Common Lisp 【发布时间】:2021-05-10 03:20:28 【问题描述】:

在带有sbcl-1.4.14 的Windows XP 机器上,我使用ASDF 安装了

(load "C:\\Program Files\\clisp-2.49\\asdf\\asdf.lisp")
(require :asdf)
(push "C:\\Documents and Settings\\mayhem\\lisp\\iterate\\" asdf:*central-registry*)

开启SLIME

(require :iterate)
(iterate (for i from 1 to 5) (collect (* i i)))

给出变量 I 未绑定错误

如果我执行(in-package :iterate),上面的代码可以正常工作,但这次熟悉的函数,如exit 和我在.sbclrc 中定义的其他函数停止工作,它们给出The function ITERATE::EXIT is undefined 类型的错误,例如。

如果我执行(use-package :iterate),那么它会给出[Condition of type NAME-CONFLICT] 错误。

于是我开始像这样使用这个包: (iterate:iterate (iterate:for i from 1 to 5) (iterate:collect (* i i))) 但我想你会同意这是一种糟糕的风格。

如何正确使用iterate

注意:我已经看到 the post 关于非常相似的问题,但它没有帮助。关于这个特定问题的帖子或文章并不多。

【问题讨论】:

对于 sbcl,请参阅 sbcl.org/manual/#Package-Variance 以了解其他错误并在包差异时重新启动 【参考方案1】:

在尝试引用 iterate 包中的不合格符号之前,您需要先说 (use-package :iterate)

你的情况是这样的。

    您已将iterate 系统加载到正在运行的Lisp 中,创建了一个名为"ITERATE" 的包。 在"CL-USER" 包中,您输入了(iterate ...),读者发现它需要查找或创建一个名称为"ITERATE" 并且可以在"CL-USER" 包中访问的符号。 没有这样的符号,所以它创建了一个新符号CL-USER::ITERATE。 这不是ITERATE:ITERATE,所以当它试图评估一个函数的参数时,你会从评估器那里得到一个错误(它不存在,但它还不知道)。实际上,您遇到的错误是在评估 (for i ...) 子表单中的第一个参数时。 现在你说(use-package :iterate) 告诉系统将"ITERATE" 包添加到"CL-USER" 的搜索列表中。 现在有一个冲突:iterate 应该引用现有的CL-USER::ITERATE 还是新可访问的ITERATE::ITERATE? (可能还有其他一些冲突)。 所以系统发出错误信号,应该有一些有用的方法可以从中继续,其中之一可能是“取消所有冲突的"CL-USER" 符号”,但我想你没有选择那个选项。 所以现在一切都搞砸了。

答案是:在尝试引用不合格符号之前,先使用要引用不合格符号的包。

(还有:Windows XP?你的复古给我留下了深刻的印象。)

【讨论】:

当我输入 (require :iterate) (use-package :iterate) 之前然后评估代码时,它终于可以工作了。我猜这里的顺序很重要。是的,我喜欢并使用 Windows XP,但对于这个特殊问题,我并没有优先使用它。我使用它是因为我的 Windows 7 在加载 ASDF 时出现问题,我也发布了一个关于它的问题:***.com/q/66061146/12212606

以上是关于在 Common Lisp 中使用 iterate 包的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 common-lisp CLOS 中指向一个 defgeneric 实例

在 common lisp 中居中文本

如何在 Common Lisp 中增加或减少数字?

在 Common Lisp (SBCL) 中处理和最小化内存使用

在 common lisp 中复制结构列表

Clojure let vs Common Lisp let