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 .

Example:

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



3.0.0.1. (cdr l)
[DX]


Returns the next elements of a list or dotted pair l .

Example:

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



3.0.0.2. (c...r l)


Letters ``...'' stands for any combination of two or three letters a or d . 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 l in reverse order.

Example:

? (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. (nth% i l)
[DE] (miscenv.lsh)


This function is similar to function nth , except it considers l as a virtualy circular list. In other words, it reduces i to the rest of its division by the length of list l . Since it calls function length, no effecive circular list should be given as argument.



3.0.0.13. (last l)
[DX]


Returns the last element of the list l .

Example:

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



3.0.0.14. (lastcdr l)
[DX]


Returns the last pair of the list l .

Example:

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



3.0.0.15. (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.16. (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.17. (flatten x)
[DX]


Returns all the 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.18. (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.19. (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.20. (alist-add key value alist)
[DE] (miscenv.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.21. (alist-get key alist)
[DE] (miscenv.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.22. (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.0.23. (sort-index l)
[DE] (miscenv.lsh)


The function sort ranks the component of its argument. Argument l may be a list or a vector.

This function returns a list wich elements of are indices of l such that its components are ranked from the biggest to the lowest.



3.0.0.24. (lbound1 l)
[DE] (miscenv.lsh)


The function lbound1 returns the dimensions of a list l .

The list l is assumed to be homogeneous, which means that the length of its member sublists have all the same length, and this in a recursive way. In other word, list l is the list counterpart of a multidimensional array.

? (lbound1 '(1 2 (3 4) 5))
= (4)



3.0.0.25. (lboundn l)
[DE] (miscenv.lsh)


The function lboundn returns the dimensions of the list l .

All lists, even unhomogeneous, are supported.

? (lboundn '(1 2 (3 4) 5))
= (4 2)



3.0.0.26. (sublist l n s1...sn)
[DE] (miscenv.lsh)


This function extracts sublists from a flat list l . The procedure follows three steps.

The following example takes a list of numbers from 0 to 99, considered as an array 5 * 20, and extracts the items in the intersection of lines 1, 2 and columns 4, 5, 6, 7.

? (sublist (range 100) '(5 ()) '(1 2) '(4 7))))
= (25 26 27 28 45 46 47 48)

? (sublist (range 0 29) 5 () '(2 3))))
= (2 3 7 8 12 13 17 18 22 23 27 28)

See: (submatrix mat s1 ...[ sn ])
See: (msplit-dim m targetdim newdims )




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] (miscenv.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] (miscenv.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] (miscenv.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.