Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return list without last element in common lisp

I wrote my silly function which returns a list without the last element in common lisp. Is there any more elegant solution to this problem?

Here's my code:

(defun list-without-last (l)
  (if (> (length (rest l)) 0)
      (append (list (first l)) (list-without-last (rest l)))
      nil))
like image 521
Sergey Avatar asked May 17 '12 13:05

Sergey


2 Answers

Short and simple, just like Lisp. Here is the magic stuff:

(defun without-last(l) (reverse (cdr (reverse l))) )

like image 114
Петре Дрварчето Avatar answered Nov 03 '22 22:11

Петре Дрварчето


Your function has two problems:

  • you are using LENGTH. LENGTH has to scan the whole list.

  • you are using APPEND. Try to use CONS. CONS is simpler.

Common Lisp also already provides this function. It is called BUTLAST.

In real code we also would not use recursion. The stack size would limit the length of lists we can process.

An iterative version using the LOOP macro:

CL-USER> (defun my-butlast (list)
           (loop for l on list
                 while (rest l)
                 collect (first l)))
MY-BUTLAST                                                                                                                                      
CL-USER> (compile 'my-butlast)
MY-BUTLAST                                                                                                                                      
NIL                                                                                                                                             
NIL                                                                                                                                             
CL-USER> (my-butlast '(1 2 3 4 5))
(1 2 3 4)                                                                                                                                       
CL-USER> (my-butlast '(1))
NIL                                                                                                                                             
CL-USER> (my-butlast '(1 2))
(1)                                                                                                                                             
like image 41
Rainer Joswig Avatar answered Nov 03 '22 23:11

Rainer Joswig