Mapcan 对原子的行为

Mapcan's behavior on atoms

我几乎是 common-lisp 的新手,只是为了好玩而使用它。但我假设知道 mapper 和 mapcan 之间的区别,因为 hyperspec 和其他地方的文档非常清楚。

但是,如果调用列表元素的函数 mapcan 的计算结果是原子而不是列表,会发生什么情况?由于mapcan使用nconc追加列表,本来以为没有列表会报错

但如果我尝试

(mapcan (lambda (x) (+ 2 x)) '(1 2 3 4))

它在 sbcl 和 clisp 中的计算结果为“6”。 (这个例子可能没有实际需要;我只是好奇)我明白了一点,即返回一个值可能比一个更简单的错误更好,但是如果没有 nconc 的列表,可以找到关于 mapcan 返回最后一个值的任何信息。

这种行为有原因吗?

根据 the documentation for mapcan (mapcan (lambda (x) (+ 2 x)) '(1 2 3 4)) 应该做与 (apply #'nconc (mapcar (lambda (x) (+ 2 x)) '(1 2 3 4))) 相同的事情,它表示错误 *** - NCONC: 5 is not a list in clisp.

hyperspec 仅显示 nconc 应该使用适当的列表和 nil 作为最后一个参数。它没有任何其他描述,所以您看到的是 sbclclisp 可能从 public 域中的 lisp 共享算法,或者他们已经实现它非常相似,他们有相同的具体实施结果。

您可能无法假设其他实现会做同样的事情,因此您应该确保传递给 mapcan 的函数总是 return 一个新列表或 nil 可以是 nconc-ed 在 the specification.