Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Lisp: first returns first, but last returns a list of last -- huh?

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!

like image 206
Olie Avatar asked Jul 18 '13 18:07

Olie


2 Answers

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
like image 67
Óscar López Avatar answered Sep 28 '22 07:09

Óscar López


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)).

like image 23
huaiyuan Avatar answered Sep 28 '22 05:09

huaiyuan