Next: , Previous: , Up: lists   [Index]

23.7 Length, append, concatenate, reverse, zip and count

Function: length+ circ

Return the length of the argument, or #f if circ is a circular list. The length of a proper list is a non–negative integer n such that cdr applied n times to the list produces the empty list.

Function: append! ell ...

Return a list consisting of the elements of ell followed by the elements of the other list arguments; it is allowed to alter cons cells in the argument lists to construct the result list. The last argument is never altered; the result list shares structure with this parameter.

(append! '(x) '(y))        ⇒  (x y)
(append! '(a) '(b c d))    ⇒  (a b c d)
(append! '(a (b)) '((c)))  ⇒  (a (b) (c))
(append! '(a b) '(c . d))  ⇒  (a b c . d)
(append! '() 'a)           ⇒  a
(append! '(x y))           ⇒  (x y)
(append!)                  ⇒  ()

Notice that append is implemented by (rnrs base (6)). (vicare-scheme)Pairs and lists.

Function: concatenate list-of-lists
Function: concatenate! list-of-lists
Syntax: concatenate/stx list-of-lists
Syntax: concatenate!/stx list-of-lists

These functions append the elements of their argument together; that is, concatenate returns:

(apply append list-of-lists)

concatenate! is allowed to alter the arguments to build the result. As with append and append!, the last element of the input list may be any value at all.

Function: reverse! list

Return a newly allocated list consisting of the elements of list in reverse order; it is allowed to alter the argument’s cons cells to produce the reversed list.

(reverse! '(a b c))              ⇒  (c b a)
(reverse! '(a (b c) d (e (f))))  ⇒  ((e (f)) d (b c) a)

Notice that reverse is implemented by (rnrs base (6)). (vicare-scheme)Pairs and lists.

Function: append-reverse rev-head tail
Function: append-reverse! rev-head tail
Syntax: append-reverse/stx rev-head tail
Syntax: append-reverse!/stx rev-head tail

append-reverse returns:

(append (reverse rev-head) tail)

It is provided because it is a common operation; a common list–processing style calls for this exact operation to transfer values accumulated in reverse order onto the front of another list, and because the implementation is significantly more efficient than the simple composition it replaces.

But note that this pattern of iterative computation followed by a reverse can frequently be rewritten as a recursion, dispensing with the reverse and append-reverse steps, and shifting temporary, intermediate storage from the heap to the stack, which is typically a win for reasons of cache locality and eager storage reclamation.

append-reverse! is allowed to alter rev-head’s cons cells to construct the result.

Function: zip list1 list ...
Function: zip* circ1 circ ...
Syntax: zip/stx ?list1 ?list ...
Syntax: zip*/stx ?circ1 ?circ ...

The function zip is defined as:

(lambda ells (apply map list ells))

while zip* is defined as:

(lambda ells (apply map* list ells))

If zip* is passed n lists, it returns a list as long as the shortest of these lists, each element of which is an n–element list comprised of the corresponding elements from the parameter lists.

(zip* '(one two three)
      '(1 2 3)
      '(odd even odd even odd even odd even))
⇒ ((one 1 odd) (two 2 even) (three 3 odd))

(zip* '(1 2 3))
⇒ ((1) (2) (3))

When applying zip*, at least one of the argument lists must be finite:

(zip* '(3 1 4 1)
      (circular-list #f #t))
⇒ ((3 #f)
    (1 #t)
    (4 #f)
    (1 #t))
Function: unzip1 ell
Function: unzip2 ell
Function: unzip3 ell
Function: unzip4 ell
Function: unzip5 ell
Syntax: unzip1/stx ell
Syntax: unzip2/stx ell
Syntax: unzip3/stx ell
Syntax: unzip4/stx ell
Syntax: unzip5/stx ell

unzip1 takes a list of lists, where every list must contain at least one element, and returns a list containing the initial element of each such list. That is, it returns (map car lists).

unzip2 takes a list of lists, where every list must contain at least two elements, and returns two values: a list of the first elements, and a list of the second elements.

unzip3 does the same for the first three elements of the lists, and so forth.

(unzip2 '((1 one) (2 two) (3 three)))
⇒ (1 2 3)
   (one two three)
Function: count pred circ ...
Syntax: count/stx pred circ ...

pred is a procedure taking as many arguments as there are lists and returning a single value. It is applied element–wise to the elements of the lists, and a count is tallied of the number of elements that produce a true value. This count is returned.

count is “iterative” in that it is guaranteed to apply pred to the list elements in a left–to–right order. The counting stops when the shortest list expires.

(count even? '(3 1 4 1 5 9 2 5 6))
⇒ 3

(count < '(1 2 4 8) '(2 4 6 8 10 12 14 16))
⇒ 3

At least one of the argument lists must be finite:

(count < '(3 1 4 1) (circular-list 1 10))
⇒ 2

Next: , Previous: , Up: lists   [Index]