在 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 实例