3.0. Lists


List are the elementary data structure in Lush. Several functions are designed for handling lists. Lists are stored as pairs (car . cdr). The first element of the pair (car) is a pointer to the first element of the list. The second element of the pair (cdr) is a pointer to the list of the remaining elements.

The textual representation of a list is composed of an opening parenthesis, a sequence of Lush objects separated by blanks and closing parenthesis. The empty list is thus written as () .

The second element (cdr) of a pair is not necessary a list. A special dotted pair notation is used for representing such a pair. This notation is composed of an opening parenthesis, the first Lush objects, a blank separated dot, the second Lush object and a closing parenthesis.

Examples:

       (1 2 3)               ; car=2 and cdr=(2 3)
       ((q w) 2)       ; car=(q w) and cdr=2
       (1 2 (e r))     ; car=1 and cdr=(2 (e r))
       (a . b)               ; car=a and cdr=b



3.0.0. List Manipulation Functions


The following functions are useful for accessing or building lists.



3.0.0.0. (car l)
[DX]


Returns the first element of a list or dotted pair l . The function name 'car' stands for contents of address register.

Example:

? (car '(a b c d))
= a



3.0.0.1. (cdr l)
[DX]


Returns the next elements, or rest, of a list or dotted pair l . The function name 'cdr' stands for contents of destination register.

Example:

? (cdr '(a b c d))
= (b c d)



3.0.0.2. (c ... r l)


This a variation on car and cdr to access specific, possibly nested, elements of a list. The ellipsis (...) stands for any two or three letter combination of the letters a or d (i.e. the address and destination). All the combinations of two car or cdr functions are written in C. The combination of three are written in Lisp in "sysenv.lsh" .

Example:

? (cadr '(a b c d))
= b



3.0.0.3. (cons a1 a2)
[DX]


Builds a list whose car is a1 and cdr a2 .

Example:

? (cons '+ '(2 3))
= (+ 2 3)

? (cons 'a 'b)
= (a . b)



3.0.0.4. (list a1 ... an)
[DY]


Builds a list with its arguments a1 to an .

Example:

? (list 'a '(b c) 'd)
= (a (b c) d)



3.0.0.5. (makelist n v)
[DX]


Returns a list containing n times element v .

Example:

? (makelist 4 'e)
= (e e e e)



3.0.0.6. (range [n1] n2 [delta])
[DX]


Returns a list of all the numbers between n1 and n2 , stepping by delta . The default value for both arguments n1 and delta is 1 .

Example:

? (range 2 5)
= (2 3 4 5)



3.0.0.7. (length l)
[DX]


Returns the length of the list l .

Example:

? (length '(a b c d e))
= 5

This function is able to detect that list l is circular. The value -1 is returned when such a condition occurs.



3.0.0.8. (append l1 ... ln)
[DX]


Concatenates lists l1 to ln . The idiom (append l ()) may be used to get a fresh copy of the list l .

Example:

? (append '(1 2 3) '(4 5 6))
= (1 2 3 4 5 6)



3.0.0.9. (reverse l)
[DX]


Returns a list of l 's toplevel elements in reverse order.

Example:

? (reverse '(1 2 3))
= (3 2 1)

? (reverse '(1 2 3)) = (3 2 1)



3.0.0.10. (nth n l)
[DX]


Returns the n th elements of the list l . The first element is numbered 0 . For compatibility with the previous versions of Lush, the syntax (nth l n) is allowed. In this case, the first element is numbered 1 .

Example:

? (nth 3 '(a b c d e))
= d



3.0.0.11. (nthcdr n l)
[DX]


Returns the n th pair of the list l . The first pair is numbered 0. This function is equivalent to n calls of the cdr functions.

Example:

? (nthcdr 3 '(a b c 3 e f))
= (3 e f)



3.0.0.12. (last l)
[DX]


Returns the last element of the list l .

Example:

? (last '(a b c 3 e f))
= f



3.0.0.13. (lastcdr l)
[DX]


Returns the last pair of the list l .

Example:

? (lastcdr '(a b c 3 e f))
= (f)



3.0.0.14. (nfirst n l)
[DX]


When n is 0, the empty list is returned.

When n is greater than 0, this function returns the n first elements of l . When the length of the list is lower than n , a copy of the list is returned.

When n is lower than 0, this function returns all elements but the n last. When the length of the list is lower than the absolute value of n , the empty list is returned. If l is a circular list, an error occurs.



3.0.0.15. (member e l)
[DX]


Searches list l for element e . If element e is not found, function member returns the empty list () . Otherwise function member returns the first sublist of l whose first element is equal to e .

There is a single equality test in Lush that is able to recursively compare lists and strings.

Example:

? (member 'e (range 1 4))
= ()

? (member 'e '(a b c d e f g h i j))
= (e f g h i j)



3.0.0.16. (flatten x)
[DX]


Returns all the non nil atoms in x , linked in a single list.

Example:

? (flatten '2)
= (2)

? (flatten '(1 2 (3 (6 7)) 4))
= (1 2 3 6 7 4)



3.0.0.17. (filter f x)
[DE]


Returns a list of those elements of x for which the application of function f to the element returns a non-nil result.



3.0.0.18. (assoc key alist)
[DX]


See: (alist-add key value alist )
See: (alist-get key alist )
See: Hash Tables.


Function assoc is useful for searching an ``alist''. An alist is a list of pairs (key . value) representing associations between a search key key and a value value .

Function assoc returns the first pair of alist whose first element is equal to key . The empty list is returned when no matching pair is found. Once the pair is located, you can acess the value associated with the key using function cdr . You can also change the value using function rplacd .

Remark: Alists should be only used for small numbers of key-value pairs. We suggest using hash tables as soon as the association involves more that twelve key-value pairs. Hash tables indeed require more memory but are much faster and much more convenient.



3.0.0.19. (alist-add key value alist)
[DE] (sysenv.lsh)


See: (assoc key alist )
This function (based on function assoc ) adds or changes a pair ( key value ), in a alist alist and returns the new alist.

This function is defined as follows:

 (de alist-add(key value alist)
   (let ((pair (assoc key alist)))
      (if pair
         (rplacd pair value)       
        (setq alist (cons (cons key value) alist)) )
      alist ) )


3.0.0.20. (alist-get key alist)
[DE] (sysenv.lsh)


See: (assoc key alist )
This function (based on function assoc ) returns the value associated to a key key in alist alist .

This function is defined as follows:

 (de alist-get(key alist)
   (let ((pair (assoc key alist)))
      (when pair
         (cdr pair) ) ) )


3.0.0.21. (sort-list l comp)
[DE] (sysenv.lsh)


Returns a sorted copy of list l according the order relation achieved by the diadic function comp .
? (sort-list '(12 3 1 2 3 4 5 6) >)
= (1 2 3 3 4 5 6 12)



3.0.1. Physical List Manipulation Functions


Instead of building new pairs, a few fast functions directly change the pointers stored in the pairs given as argument. This is safe if the programmer knows that the function's arguments are not used elsewhere.

Side effects should be expected when another lisp object points to the argument of such a physical list modification function. The modification then appears in both places.

Physical list manipulation functions can be used to construct lists that reference themselves. Some Lush functions are able to test this condition (e.g. length ) and avoid an infinite loop. Some Lush functions however (e.g. print , flatten ) will loop forever when processing such a list. You can interrupt these loops by typing Ctrl-C or Break .

See: (length l )
See: (== n1 n2 )




3.0.1.0. (rplaca l e)
[DX]


Physically replaces the "car" of list l by e .

Example:

? (setq a '(1 2 3))
= (1 2 3)
? (setq b (cdr a))
= (2 3)
? (rplaca b 'e)    ; this is fast
= (e 3)
? a                ; but causes side effects
= (1 e 3)



3.0.1.1. (rplacd l e)
[DX]


Physically replaces the cdr of list l by e .



3.0.1.2. (displace l1 l2)
[DX]


Replaces both the car and cdr of l1 by the car and cdr of l2 . The main purpose of this function is the implementation of DMD functions.



3.0.1.3. (nconc l1 ... ln)
[DE] (sysenv.lsh)


Function nconc returns the concatenation of the lists l1 to ln . It uses physical replacement and therefore causes side effects.



3.0.1.4. (nconc1 l e)
[DE] (sysenv.lsh)


Function nconc returns a list formed by appending element e to the end of list l . It uses physical replacement and therefore causes side effects.

Example:

? (setq a '(a b c d e))
= (a b c d e)
? (nconc1 a 'f)
= (a b c d e f)



3.0.1.5. (list-insert l pos x)
[DE] (sysenv.lsh)


Function list-insert returns a list formed by inserting element x at position pos of list l . It uses physical replacement and therefore causes side effects.



3.0.1.6. (list-delete l pos)
[DE] (sysenv.lsh)


Function list-insert returns a list formed by deleting the element located at position pos from list l . It uses physical replacement and therefore causes side effects.



3.0.1.7. (list-merge l l2)
[DE] (sysenv.lsh)


Function list-merge returns a list formed by appending to list l the elements of l2 that are not already in l . This function uses physical replacement and therefore causes side effects.