Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the 'cons' to add an item to the end of the list?

what's the typical way to add an item to the end of the list?

I have a list (1 2 3) and want to add 4 to it (where 4 is the result of an evaluation (+ 2 2))

(setf nlist '(1 2 3))  
(append nlist (+ 2 2))  

This says that append expects a list, not a number. How would I accomplish this?

like image 831
r b Avatar asked Jun 22 '11 12:06

r b


People also ask

What does cons do in scheme?

The other constructor, cons , is used when you already have a list and you want to add one new element. Cons takes two arguments, an element and a list (in that order), and returns a new list whose car is the first argument and whose cdr is the second.

What is the difference between appending a list and extending a list?

append() adds a single element to the end of the list while . extend() can add multiple individual elements to the end of the list. Argument: . append() takes a single element as argument while .


2 Answers

You could use append, but beware that it can lead to bad performance if used in a loop or on very long lists.

(append '(1 2 3) (list (+ 2 2)))

If performance is important, the usual idiom is building lists by prepending (using cons), then reverse (or nreverse).

like image 179
danlei Avatar answered Sep 20 '22 01:09

danlei


If the "cons at the front, finish by reversing" idiom isn't suitable for you (if you. for example, need to pass the list on to other functions DURING its construction), there's also the "keep track of the end" trick. However, it's probably cleaner to just build the list by consing to the front of it, then finish by using reverse or nreverse before finally using it.

In essence, this allows you to have the list in the right order while building it, at the expense of needing to keep track of it.

(defun track-tail (count)
  (let* ((list (cons 0 nil))
         (tail list))
    (loop for n from 1 below count
       do (progn
        (setf (cdr tail) (cons n nil))
        (setf tail (cdr tail))
        (format t "With n == ~d, the list is ~a~%" n list)))
    list))

This gives the following output:

CL-USER> (track-tail 5)
With n == 1, the list is (0 1)
With n == 2, the list is (0 1 2)
With n == 3, the list is (0 1 2 3)
With n == 4, the list is (0 1 2 3 4)
(0 1 2 3 4)
like image 21
Vatine Avatar answered Sep 20 '22 01:09

Vatine