问题描述
常见Lisp:简介中有一个问题。问题是要在列表中获取 last 元素,而不是 cons cell 。宏LAST
返回点分列表中的cons cell
。提出的问题是使用宏reverse
而不是last
,但是clisp
和sbcl
都抛出错误。
(reverse '(a b c . d))
=> error
CLHS文档说,我们只能反转适当的列表(序列),而不能反转点列表或循环列表。
编辑
我已经使用LAST
编写了程序。
(defun last-element (x)
"x is a list with last element as dotted pair"
(cdr (last x)))
我不确定在这种情况下如何使用reverse
。
解决方法
只要列表不是循环的,函数last
就会返回任何正确列表或点分列表的最后一个cons
单元格。
听起来问题在于练习6.6:
使用LAST函数编写一个名为LAST-ELEMENT的函数,该函数返回列表的最后一个元素而不是最后一个cons单元格。使用REVERSE而不是LAST编写另一个版本的LAST-ELEMENT。使用NTH和LENGTH编写另一个版本。
如果这样做的话,本练习将指定点列表输入。 When list is used in an unqualified way,it almost always means proper list。对于正确的列表,last
将返回cons
中带有nil
的{{1}}单元格,例如cdr
-> (last '(a b c d)
,或者只是(d . nil)
,因此适当列表的最后一个元素是最后一个(d)
单元格的car
。
如果您要同时处理正确的列表和点分列表,则需要确定输入内容并进行相应的处理:对于点分列表,最后的“元素”将是最后一个{{1 }} 细胞。相应地处理cons
版本的输入意味着您必须在应用cdr
之前确定输入是正确的列表还是虚线列表。您可以编写一个函数,以在使用cons
之前将点分列表转换为正确的列表。
从技术上讲,the Standard does not consider the atom which terminates a dotted list to be one of its elements:
元素1.(列表中的)一个对象,它是构成列表的其中一项简而言之的汽车。
对于像reverse
这样的适当列表,reverse
是终止原子(因为reverse
与(a b c d)
相同),而nil
是最后一个缺点; (a b c d)
是最后一个(a b c d . nil)
的{{1}},因此是列表的最后一个元素。对于像(d . nil)
这样的虚线列表,d
是终止原子,而car
是最后一个cons
。由于(a b c . d)
是最后一个d
的{{1}},因此(c . d)
是标准中定义的最后一个真正的元素。虚线列表。可以说cons
是c
的最后一个成员。
但是,通用Lisp:轻松介绍中的练习6.6仅适用于正确的列表。