Lisp 公共口齿不清:first返回first,但last返回last的列表,嗯?

Lisp 公共口齿不清:first返回first,但last返回last的列表,嗯?,lisp,common-lisp,Lisp,Common Lisp,我不会用Common Lisp来理解这个第一/最后的东西。是的,我知道它是怎么工作的,但我不明白为什么它是这样工作的 基本上,要获取列表中的第一项,我可以使用(first mylist)。但是,如果我想要最后一项,(最后一个mylist)不会给我这个;相反,它给了我一个包含列表中最后一项的列表 (我使用的是Clozure CL,它还有一些其他的奇怪之处,在我看来像是bug,但是,因为我是Lisp-n00b,所以我尽量不相信旧的“解释器坏了!”把戏:) 例如: ? (setq x '((1 2)

我不会用Common Lisp来理解这个第一/最后的东西。是的,我知道它是怎么工作的,但我不明白为什么它是这样工作的

基本上,要获取列表中的第一项,我可以使用
(first mylist)
。但是,如果我想要最后一项,
(最后一个mylist)
不会给我这个;相反,它给了我一个包含列表中最后一项的列表

(我使用的是Clozure CL,它还有一些其他的奇怪之处,在我看来像是bug,但是,因为我是Lisp-n00b,所以我尽量不相信旧的“解释器坏了!”把戏:)

例如:

? (setq x '((1 2) (a b)))
=> ((1 2) (A B))

? (first x)
=> (1 2)  ; as expected

? (last x)
=> ((A B))  ; why a list with my answer in it?!

? (first (last x))
=> '(A B)  ; This is the answer I'd expect from plain-old (last x)
(setq x (list 'a 'b 'c 'd))
(last x) =>  (d)
有人能帮我理解为什么last这么做吗?我是否错误地使用了这些项目?
first
真的是个奇怪的球吗


谢谢

在Common Lisp
last
中,应该从以下位置返回一个列表:

last返回列表的最后n个conses(不是最后n个元素)。如果list为(),则last返回()

例如:

? (setq x '((1 2) (a b)))
=> ((1 2) (A B))

? (first x)
=> (1 2)  ; as expected

? (last x)
=> ((A B))  ; why a list with my answer in it?!

? (first (last x))
=> '(A B)  ; This is the answer I'd expect from plain-old (last x)
(setq x (list 'a 'b 'c 'd))
(last x) =>  (d)
是的,这是违反直觉的。在Lisp的其他版本中,它的作用正如名称所示,例如在Racket(一种Scheme方言)中:


Common Lisp的错误命名函数提供了最后一个cons

它可能应该被称为
tail
,因为它有一个函数,但我猜这个名字是因为历史/兼容性的原因而存在的


通常,它会给出列表的第n个尾部,或列表末尾前的第n个cons。

这就是它的方式
first
last
不是一对互补的操作
last
rest
nthcdr
的关系更为密切。还有一个
butlast
,它构造一个新列表,从给定列表中省略最后一项


get
getf
set
setf
无关相比,
first
last
相比,返回最后一个元素除了访问最后一个元素之外没有什么用处;返回最后一个cons可以执行以下操作:

(let ((x (list 1 2 3)))
  (setf (cdr (last x)) '(4))
  x)

=> '(1 2 3 4)

虽然您仍然可以访问最后一个元素,如
(car(last x))

LOL:first vs last get[f]vs set[f]--是的!就像他们故意弄乱N00B的脑袋一样!好的,那很有用。我想我只是想确认我没有完全错过这条船,因为第一个/最后一个不是匹配的一对,这似乎是违反直觉的。好的,接受了,谢谢其他例子。我只是想确保我没有完全忽略一些关键点,因为第一个/最后一个不匹配与语言的其他部分相比似乎太不雅观了(尽管Kaz关于get[f]/set[f]的观点也很有趣:))我想,做“(”(12)”(ab))并不是你真正的意思。使用“((1 2)(a b))代替。您所写的内容创建了以下列表:((引用(12))(引用(a b)))。这里,这两个“引号”并没有被解释为您可能指的特殊运算符,而只是简单的旧符号,它们碰巧有相同的名称。要了解我的意思,请在您的回复中评估(第一个“(”(1 2)”(a b)))。托马斯:你说得对。来源编辑。