3.9 Pairs and Lists
A pair combines exactly two values. The first value is accessed with the car procedure, and the second value is accessed with the cdr procedure. Pairs are not mutable (but see Mutable Pairs and Lists).
A list is recursively defined: it is either the constant null, or it is a pair whose second value is a list.
A list can be used as a single-valued sequence (see Sequences). The elements of the list serve as elements of the sequence. See also in-list.
Cyclic data structures can be created using only immutable pairs via read or make-reader-graph. If starting with a pair and using some number of cdrs returns to the starting pair, then the pair is not a list.
3.9.1 Pair Constructors and Selectors
v : any/c |
Returns #t if v is a pair, #f otherwise.
v : any/c |
Returns #t if v is the empty list, #f otherwise.
a : any/c |
d : any/c |
Returns a pair whose first element is a and second element is d.
p : pair? |
Returns the first element of the pair p.
p : pair? |
Returns the second element of the pair p.
The empty list.
v : any/c |
Returns #t if v is a list: either the empty list, or a pair whose second element is a list. This procedure takes amortized constant time.
v : any/c |
Returns a newly allocated list containing the vs as its elements.
v : any/c |
tail : any/c |
Like list, but the last argument is used as the tail of the result, instead of the final element. The result is a list only if the last argument is a list.
(build-list n proc) → list? |
proc : (exact-nonnegative-integer? . -> . any) |
Creates a list of n elements by applying proc to the integers from 0 to (sub1 n) in order. If lst is the resulting list, then (list-ref lst i) is the value produced by (proc i).
Examples: |
> (build-list 10 values) |
(0 1 2 3 4 5 6 7 8 9) |
> (build-list 5 (lambda (x) (* x x))) |
(0 1 4 9 16) |
3.9.2 List Operations
(length lst) → nonnegative-exact-integer? |
lst : list? |
Returns the number of elements in lst.
lst : any/c |
pos : nonnegative-exact-integer? |
Returns the element of lst at position pos, where the list’s first element is position 0. If the list has pos or fewer elements, then the exn:fail:contract exception is raised.
The lst argument need not actually be a list; lst must merely start with a chain of at least pos pairs.
lst : any/c |
pos : nonnegative-exact-integer? |
Returns the list after the first pos elements of lst. If the list has fewer than pos elements, then the exn:fail:contract exception is raised.
The lst argument need not actually be a list; lst must merely start with a chain of at least pos pairs.
lst : list? |
lst : list? |
v : any/c |
When given all list arguments, the result is a lists that contains all of the elements of the given lists in order. The last argument is used directly in the tail of the result.
The last argument need not be a list, in which case the result is an “improper list.”
lst : list? |
Returns a list that has the same elements as lst, but in reverse order.
3.9.3 List Iteration
proc : procedure? |
lst : list? |
Applies proc to the elements of the lsts from the first elements to the last, returning #f as soon as any application returns #f. The proc argument must accept the same number of arguments as the number of supplied lsts, and all lsts must have the same number of elements. The result is a list containing each result of proc.
proc : procedure? |
lst : list? |
Similar to map, except that
the result is #f if any application of proc produces #f, in which case proc is not applied to later elements of the lsts; or
the result is that of proc applied to the last elements of the lstss; more specifically, the application of proc to the last elements in the lsts is in tail position with respect to the andmap call.
If the lsts are empty, then #t is returned.
Examples: |
#t |
positive?: expects argument of type <real number>; given a |
#f |
9 |
proc : procedure? |
lst : list? |
Similar to map, except that
the result is #f if every application of proc produces #f; or
the result of the first applciation of proc to produces a value other than #f, in which case proc is not applied to later elements of the lsts; more specifically, the application of proc to the last elements in the lsts is in tail position with respect to the andmap call.
If the lsts are empty, then #f is returned.
Examples: |
#t |
#t |
5 |
proc : procedure? |
lst : list? |
Similar to map, but proc is called only for its effect, and its result (which can be any number of values) is ignored.
proc : procedure? |
init : any/c |
lst : list? |
Like map, foldl applies a procedure to the elements of one or more lists. Whereas map combines the return values into a list, foldl combines the return values in an arbitrary way that is determined by proc.
If foldl is called with n lists, then proc must take n+1 arguments. The extra argument is the combined return values so far. The proc is initially invoked with the first item of each list, and the final argument is init. In subsequent invocations of proc, the last argument is the return value from the previous invocation of proc. The input lsts are traversed from left to right, and the result of the whole foldl application is the result of the last application of proc. If the lsts are empty, the result is init.
Unlike foldr, foldl processes the lsts in constant space (plus the space for each call to proc).
Examples: |
(4 3 2 1) |
10 |
proc : procedure? |
init : any/c |
lst : list? |
Like foldl, but the lists are traversed from right to left. Unlike foldl, foldr processes the lsts in space proportional to the length of lsts (plus the space for each call to proc).
Examples: |
(1 2 3 4) |
(2 3 4 5) |
3.9.4 List Filtering
pred : procedure? |
lst : list? |
Returns a list with the elements of lst for which pred produces a true value. The pred procedure is applied to each element from first to last.
v : any/c |
lst : list? |
proc : procedure? = equal? |
Returns a list that is like lst, omitting the first element of lst that is equal to v using the comparison procedure proc (which must accept two arguments).
v : any/c |
lst : list? |
v : any/c |
lst : list? |
v-lst : list? |
lst : list? |
proc : procedure? = equal? |
Like remove, but removes from lst every instance of every element of v-lst.
v : any/c |
lst : list? |
v : any/c |
lst : list? |
| ||||||||||||||||||||||||||||
lst : list? | ||||||||||||||||||||||||||||
cache-keys? : boolean? = #f |
Returns a list sorted according to the less-than? procedure, which takes two elements of lst and returns a true value if the first is less than (i.e., should be sorted earlier) than the second.
The sort is stable; if two elements of lst are “equal” (i.e., proc does not return a true value when given the pair in either order), then the elements preserve their relative order from lst in the output list. To preserve this guarantee, use sort with a strict comparison functions (e.g., < or string<?; not <= or string<=?).
The #:key argument extract-key is used to extract a key value for comparison from each list element. That is, the full comparison procedure is essentially
(lambda (x y) |
(less-than? (extract-key x) (extract-key y))) |
By default, extract-key is applied to two list elements for every comparison, but if cache-keys? is true, then the extract-key function is used exactly once for each list item. Supply a true value for cache-keys? when extract-key is an expensive operation; for example, if file-or-directory-modify-seconds is used to extract a timestamp for every file in a list, then cache-keys? should be #t to minimize file-system calls, but if extract-key is car, then cache-keys? should be #f. As another example, providing extract-key as (lambda (x) (random)) and #t for cache-keys? effectively shuffles the list.
Examples: | ||
(1 2 3 4) | ||
("aardvark" "bear" "cow" "dingo") | ||
| ||
(("aardvark") ("bear") ("cow") ("dingo")) |
3.9.5 List Searching
v : any/c |
lst : list? |
Locates the first element of lst that is equal? to v. If such an element exists, the tail of lst starting with that element is returned. Otherwise, the result is #f.
v : any/c |
lst : list? |
Like member, but finds an element using eqv?.
v : any/c |
lst : list? |
Like member, but finds an element using eq?.
proc : procedure? |
lst : list? |
Like member, but finds an element using the predicate proc; an element is found when proc applied to the element returns a true value.
proc : procedure? |
lst : list? |
Like memf, but returns the element or #f instead of a tail of lst or #f.
v : any/c |
Locates the first element of lst whose car is equal? to v. If such an element exists, the pair (i.e., an element of lst) is returned. Otherwise, the result is #f.
v : any/c |
Like assoc, but finds an element using eqv?.
v : any/c |
Like assoc, but finds an element using eq?.
proc : procedure? |
lst : list? |
Like assoc, but finds an element using the predicate proc; an element is found when proc applied to the car of an lst element returns a true value.
3.9.6 Pair Accessor Shorthands
Returns (car (car p))
Returns (car (cdr p))
Returns (cdr (car p))
Returns (cdr (cdr p))
Returns (car (car (car p)))
Returns (car (car (cdr p)))
Returns (car (cdr (car p)))
Returns (car (cdr (cdr p)))
Returns (cdr (car (car p)))
Returns (cdr (car (cdr p)))
Returns (cdr (cdr (car p)))
Returns (cdr (cdr (cdr p)))
Returns (car (car (car (car p))))
Returns (car (car (car (cdr p))))
Returns (car (car (cdr (car p))))
Returns (car (car (cdr (cdr p))))
Returns (car (cdr (car (car p))))
Returns (car (cdr (car (cdr p))))
Returns (car (cdr (cdr (car p))))
Returns (car (cdr (cdr (cdr p))))
Returns (cdr (car (car (car p))))
Returns (cdr (car (car (cdr p))))
Returns (cdr (car (cdr (car p))))
Returns (cdr (car (cdr (cdr p))))
Returns (cdr (cdr (car (car p))))
Returns (cdr (cdr (car (cdr p))))
Returns (cdr (cdr (cdr (car p))))
Returns (cdr (cdr (cdr (cdr p))))
3.9.7 Additional List Functions and Synonyms
The bindings documented in this section are provided by the scheme/list and scheme libraries, but not scheme/base.
The empty list.
v : any/c |
The same as (pair? v).
v : any/c |
The same as (null? v).
lst : list? |
The same as (car lst), but only for lists (that are not empty).
lst : list? |
The same as (cdr lst), but only for lists (that are not empty).
lst : list? |
Returns the second element of the list.
lst : list? |
Returns the third element of the list.
lst : list? |
Returns the fourth element of the list.
lst : list? |
Returns the fifth element of the list.
lst : list? |
Returns the sixth element of the list.
lst : list? |
Returns the seventh element of the list.
lst : list? |
Returns the eighth element of the list.
lst : list? |
Returns the ninth element of the list.
lst : list? |
Returns the tenth element of the list.
lst : list? |
Returns the last element of the list.
p : pair? |
Returns the last pair of a (possibly improper) list.
lst : any/c |
pos : nonnegative-exact-integer? |
Synonym for list-tail.
lst : any/c |
pos : nonnegative-exact-integer? |
Returns a fresh list whose elements are the first pos elements of lst. If lst has fewer than pos elements, the exn:fail:contract exception is raised.
The lst argument need not actually be a list; lst must merely start with a chain of at least pos pairs.
Examples: |
> (take '(1 2 3 4) 2) |
(1 2) |
> (take 'non-list 0) |
() |
(add-between lst v) → list? |
lst : list? |
v : any/c |
Returns a list with the same elements as lst, but with v between each pair of items in lst.
Examples: |
> (add-between '(x y z) 'or) |
(x or y or z) |
> (add-between '(x) 'or) |
(x) |
lst : list? |
lst : list? |
lsts : list? |
Like append, but the last argument is used as a list of arguments for append, so (append* lst ... lsts) is the same as (apply append lst ... lsts). In other words, the relationship between append and append* is similar to the one between list and list*.
Examples: | ||
> (append* '(a) '(b) '((c) (d))) | ||
(a b c d) | ||
| ||
("Alpha" ", " "Beta" ", " "Gamma") |
v : any/c |
Flattens an arbitrary S-expression structure of pairs into a list. More precisely, v is treated as a binary tree where pairs are interior nodes, and the resulting list contains all of the non-null leaves of the tree in the same order as an inorder traversal.
Examples: |
> (flatten '((a) b (c (d) . e) ())) |
(a b c d e) |
> (flatten 'a) |
(a) |
(remove-duplicates lst [same?]) → list? |
lst : list? |
Returns a list that has all items in lst, but without duplicate items, where same? determines whether two elements of the list are equivalent. The resulting list is in the same order as lst, and for any item that occurs multiple times, the first one is kept.
Examples: |
> (remove-duplicates '(a b b a)) |
(a b) |
> (remove-duplicates '(1 2 1.0 0)) |
(1 2 1.0 0) |
> (remove-duplicates '(1 2 1.0 0) =) |
(1 2 0) |
(filter-map proc lst ) → list? |
proc : procedure? |
lst : list? |
Returns (filter (lambda (x) x) (map proc lst ...)), but without building the intermediate list.
| ||||||||
pred : procedure? | ||||||||
lst : list? |
Similar to filter, except that two values are returned: the items for which pred returns a true value, and the items for which pred returns #f.
The result is the same as
(values (filter pred lst) (filter (negate pred) lst))
but pred is applied to each item in lst only once.
Examples: |
(2 4 6) |
(1 3 5) |
(append-map proc lst ) → list? |
proc : procedure? |
lst : list? |
Returns (append* (map proc lst ...)).
Examples: |
> (append-map vector->list '(#(1) #(2 3) #(4))) |
(1 2 3 4) |
(filter-not pred lst) → list? |
lst : list? |
Like filter, but the meaning of the pred predicate is reversed: the result is a list of all items for which pred returns #f.
Examples: |
> (filter-not even? '(1 2 3 4 5 6)) |
(1 3 5) |
3.9.8 Immutable Cyclic Data
(make-reader-graph v) → any/c |
v : any/c |
Returns a value like v, with placeholders created by make-placeholder replaced with the values that they contain, and with placeholders created by make-hash-placeholder with an immutable hash table. No part of v is mutated; instead, parts of v are copied as necessary to construct the resulting graph, where at most one copy is created for any given value.
Since the copied vales can be immutable, and since the copy is also immutable, make-reader-graph can cycles involving only immutable pairs, vectors, boxes, and hash tables.
Only the following kinds of values are copied and traversed to detect placeholders:
pairs
immutable pairs (as created by mcons)
vectors, both mutable and immutable
boxes, both mutable and immutable
hash tables, both mutable and immutable
instances of a prefab structure type
placeholders created by make-placeholder and make-hash-placeholder
Due to these restrictions, make-reader-graph creates exactly the same sort of cyclic values as read.
Examples: | ||||
| ||||
#0=(1 . #0#) |
(placeholder? v) → boolean? |
v : any/c |
Returns #t if v is a placeholder created by make-placeholder, #f otherwise.
(make-placeholder v) → placeholder? |
v : any/c |
Returns a placeholder for use with placeholder-set! and make-reader-graph. The v argument supplies the initial value for the placeholder.
(placeholder-set! ph datum) → void? |
ph : placeholder? |
datum : any/c |
Changes the value of ph to v.
(placeholder-get ph) → any/c |
ph : placeholder? |
Returns the value of ph.
(hash-placeholder? v) → boolean? |
v : any/c |
Returns #t if v is a placeholder created by make-hash-placeholder, #f otherwise.
(make-hash-placeholder assocs) → hash-placeholder? |
Like make-immutable-hash, but produces a table placeholder for use with make-reader-graph.
(make-hasheq-placeholder assocs) → hash-placeholder? |
Like make-immutable-hasheq, but produces a table placeholder for use with make-reader-graph.