I'm not getting this first/last thing in Common-Lisp. Yes, I see how it works, but I don't get WHY it works that way.
Basically, to get the first item in a list, I can use (first mylist)
. However, if I want the last item, (last mylist)
doesn't give me that; instead, it gives me a list containing the last item in my list!
(I'm using Clozure-CL, which has a few other oddities that seem like bugs to me but, since I'm a Lisp-n00b, I'm trying not to fall for the old "the interpreter is broken!" trick :) )
So, for example:
? (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)
Can someone help me understand why last does this? Am I using these items incorrectly? Is first
really the odd-ball?!
Thanks!
In Common Lisp last
is supposed to return a list, from the documentation:
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.
last returns the last n conses (not the last n elements) of list. If list is (), last returns ().
For example:
(setq x (list 'a 'b 'c 'd))
(last x) => (d)
And yes, this is counterintuitive. In other flavors of Lisp it works as the name suggests, for example in Racket (a Scheme dialect):
(define x '((1 2) (a b)))
(first x) => '(1 2)
(last x) => '(a b)
(define x (list 'a 'b 'c 'd))
(last x) => 'd
Returning the last element is not very useful except to access the last element; returning the last cons lets you do something like this:
(let ((x (list 1 2 3)))
(setf (cdr (last x)) '(4))
x)
=> '(1 2 3 4)
while you can still access the last element as (car (last x))
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With