Common Lisp:first先返回,但是last返回最后一个列表 - 呵呵?

Oli*_*lie 5 lisp common-lisp

我在Common-Lisp中没有得到第一个/最后一个.是的,我知道它是如何工作的,但是我不知道为什么它会这样运作.

基本上,为了获得列表中的第一项,我可以使用(first mylist).但是,如果我想要最后一项,(last mylist)不要给我那个; 相反,它给了我一个包含我列表中最后一项的列表!

(我正在使用Clozure-CL,它有一些其他奇怪的东西对我来说似乎是错误但是,因为我是一个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)
Run Code Online (Sandbox Code Playgroud)

有人能帮助我理解为什么最后这样做吗?我错误地使用这些物品了吗?是否first真的是奇数球?

谢谢!

Ósc*_*pez 8

在Common Lisp last中应该从文档中返回一个列表:

last list &optional n => tail
list---a list, which might be a dotted list but must not be a circular list.
n---a non-negative integer. The default is 1.
tail---an object. 
Run Code Online (Sandbox Code Playgroud)

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

例如:

(setq x (list 'a 'b 'c 'd))
(last x) =>  (d)
Run Code Online (Sandbox Code Playgroud)

是的,这是违反直觉的.在Lisp的其他版本中,它的名称表明,例如在Racket(Scheme方言)中:

(define x '((1 2) (a b)))
(first x) => '(1 2)
(last x) => '(a b)

(define x (list 'a 'b 'c 'd))
(last x) =>  'd
Run Code Online (Sandbox Code Playgroud)


hua*_*uan 7

除了访问最后一个元素之外,返回最后一个元素并不是很有用; 返回最后一个缺点让你做这样的事情:

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

=> '(1 2 3 4)
Run Code Online (Sandbox Code Playgroud)

虽然你仍然可以访问最后一个元素(car (last x)).


ace*_*ent 5

Common Lisp 的错误命名函数last给了你最后一个缺点

它可能应该被称为tail,因为有一个函数tailp,但我的猜测是这个名称由于历史/兼容性原因而被保留。

一般来说,它给出列表的第 n 个尾部,或者列表末尾之前的第 n 个cons。