cyclone/docs/api/srfi/1.md
Justin Ethier dadf091fa5 WIP
2016-12-02 03:31:30 +00:00

1013 lines
29 KiB
Markdown

# SRFI 1 - List library
The `(srfi 1)` provides a coherent and comprehensive set of list-processing procedures.
See the [SRFI document](http://srfi.schemers.org/srfi-1/srfi-1.html) for more information.
## Constructors
[`xcons`](#xcons)
[`cons*`](#cons)
[`make-list`](#make-list)
[`list-tabulate`](#list-tabulate)
[`list-copy`](#list-copy)
[`circular-list`](#circular-list-1)
[`iota`](#iota)
## Predicates
[`proper-list?`](#proper-list)
[`circular-list?`](#circular-list)
[`dotted-list?`](#dotted-list)
[`not-pair?`](#not-pair)
[`null-list?`](#null-list)
[`list=`](#list=)
## Selectors
[`first`](#first)
[`second`](#second)
[`third`](#third)
[`fourth`](#fourth)
[`fifth`](#fifth)
[`sixth`](#sixth)
[`seventh`](#seventh)
[`eighth`](#eighth)
[`ninth`](#ninth)
[`tenth`](#tenth)
[`car+cdr`](#carcdr)
[`take`](#take)
[`drop`](#drop)
[`take-right`](#take-right)
[`drop-right`](#drop-right)
[`take!`](#take-1)
[`drop-right!`](#drop-right-1)
[`split-at`](#split-at)
[`split-at!`](#split-at-1)
[`last`](#last)
[`last-pair`](#last-pair)
## Miscellaneous: length, append, concatenate, reverse, zip, and count
[`length+`](#length)
[`zip`](#zip)
[`unzip1`](#unzip1)
[`unzip2`](#unzip2)
[`unzip3`](#unzip3)
[`unzip4`](#unzip4)
[`unzip5`](#unzip5)
[`count`](#count)
[`append!`](#append)
[`append-reverse`](#append-reverse)
[`append-reverse!`](#append-reverse-1)
[`concatenate`](#concatenate)
[`concatenate!`](#concatenate-1)
[`reverse!`](#reverse)
## Fold, unfold, and map
[`unfold`](#unfold)
[`fold`](#fold)
[`pair-fold`](#pair-fold)
[`reduce`](#reduce)
[`unfold-right`](#unfold-right)
[`fold-right`](#fold-right)
[`pair-fold-right`](#pair-fold-right)
[`reduce-right`](#reduce-right)
[`append-map`](#append-map)
[`append-map!`](#append-map-1)
[`map!`](#map)
[`pair-for-each`](#pair-for-each)
[`filter-map`](#filter-map)
[`map-in-order`](#map-in-order)
## Filtering and partitioning
[`filter`](#filter)
[`partition`](#partition)
[`remove`](#remove)
[`filter!`](#filter-1)
[`partition!`](#partition-1)
[`remove!`](#remove-1)
## Searching
[`find`](#find)
[`find-tail`](#find-tail)
[`any`](#any)
[`every`](#every)
[`list-index`](#list-index)
[`take-while`](#take-while)
[`drop-while`](#drop-while)
[`take-while!`](#take-while-1)
[`span`](#span)
[`break`](#break)
[`span!`](#span-1)
[`break!`](#break-1)
## Deleting
[`delete`](#delete)
[`delete!`](#delete-1)
[`delete-duplicates`](#delete-duplicates)
[`delete-duplicates!`](#delete-duplicates-1)
## Association lists
[`alist-cons`](#alist-cons)
[`alist-copy`](#alist-copy)
[`alist-delete`](#alist-delete)
[`alist-delete!`](#alist-delete-1)
## Set operations on lists
[`lset<=`](#lset)
[`lset=`](#lset-1)
[`lset-adjoin`](#lset-adjoin)
[`lset-union`](#lset-union)
[`lset-intersection`](#lset-intersection)
[`lset-difference`](#lset-difference)
[`lset-xor`](#lset-xor)
[`lset-diff+intersection`](#lset-diffintersection)
[`lset-union!`](#lset-union)
[`lset-intersection!`](#lset-intersection-1)
[`lset-difference!`](#lset-difference-1)
[`lset-xor!`](#lset-xor-1)
# xcons
(xcons d a)
Equivalent to:
(lambda (d a) (cons a d))
Of utility only as a value to be conveniently passed to higher-order procedures.
(xcons '(b c) 'a) => (a b c)
The name stands for "eXchanged CONS."
# cons*
(cons* elt1 elt2 ...)
Like list, but the last argument provides the tail of the constructed list, returning
(cons elt1 (cons elt2 (cons ... eltn)))
This function is called `list*` in Common Lisp and about half of the Schemes that provide it, and `cons*` in the other half.
(cons* 1 2 3 4) => (1 2 3 . 4)
(cons* 1) => 1
# make-list
(make-list n)
(make-list n fill)
Returns an n-element list, whose elements are all the value `fill`. If the fill argument is not given, the elements of the list may be arbitrary values.
(make-list 4 'c) => (c c c c)
# list-tabulate
(list-tabulate n init-proc)
Returns an n-element list. Element `i` of the list, where `0 <= i < n`, is produced by `(init-proc i)`. No guarantee is made about the dynamic order in which init-proc is applied to these indices.
(list-tabulate 4 values) => (0 1 2 3)
# list-copy
(list-copy flist)
Copies the spine of the argument.
# circular-list
(circular-list elt1 elt2 ...)
Constructs a circular list of the elements.
(circular-list 'z 'q) => (z q z q z q ...)
# iota
(iota count)
(iota count start)
(iota count start step)
Returns a list containing the elements
(start start+step ... start+(count-1)*step)
The `start` and `step` parameters default to 0 and 1, respectively. This procedure takes its name from the APL primitive.
(iota 5) => (0 1 2 3 4)
(iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)
# proper-list?
(proper-list? x)
Returns true iff `x` is a proper list -- a finite, nil-terminated list.
More carefully: The empty list is a proper list. A pair whose cdr is a proper list is also a proper list:
<proper-list> ::= () (Empty proper list)
| (cons <x> <proper-list>) (Proper-list pair)
Note that this definition rules out circular lists. This function is required to detect this case and return false.
Nil-terminated lists are called "proper" lists by R7RS and Common Lisp. The opposite of proper is improper.
# circular-list?
(circular-list? x)
True if `x` is a circular list. A circular list is a value such that for every `n >= 0`, the `n`th `cdr(x)` is a pair.
Terminology: The opposite of circular is finite.
(not (circular-list? x)) = (or (proper-list? x) (dotted-list? x))
# dotted-list?
(dotted-list? x)
True if `x` is a finite, non-nil-terminated list. That is, there exists an `n >= 0` such that the `n`th `cdr(x)` is neither a pair nor (). This includes non-pair, non-() values (e.g. symbols, numbers), which are considered to be dotted lists of length 0.
(not (dotted-list? x)) = (or (proper-list? x) (circular-list? x))
# not-pair?
(not-pair? x)
Equivalent to:
(lambda (x) (not (pair? x)))
Provided as a procedure as it can be useful as the termination condition for list-processing procedures that wish to handle all finite lists, both proper and dotted.
# null-list?
(null-list? list)
`list` is a proper or circular list. This procedure returns true if the argument is the empty list (), and false otherwise. It is an error to pass this procedure a value which is not a proper or circular list. This procedure is recommended as the termination condition for list-processing procedures that are not defined on dotted lists.
# list=
(list= elt= list1 ...)
Determines list equality, given an element-equality procedure. Proper list A equals proper list B if they are of the same length, and their corresponding elements are equal, as determined by `elt=`. If the element-comparison procedure's first argument is from listi, then its second argument is from listi+1, i.e. it is always called as `(elt= a b)` for a an element of list A, and b an element of list B.
In the n-ary case, every list `i` is compared to list `i+1` (as opposed, for example, to comparing list element `1` to every list element `i`, for `i>1`). If there are no list arguments at all, list= simply returns true.
It is an error to apply list= to anything except proper lists. While implementations may choose to extend it to circular lists, note that it cannot reasonably be extended to dotted lists, as it provides no way to specify an equality procedure for comparing the list terminators.
Note that the dynamic order in which the elt= procedure is applied to pairs of elements is not specified. For example, if list= is applied to three lists, A, B, and C, it may first completely compare A to B, then compare B to C, or it may compare the first elements of A and B, then the first elements of B and C, then the second elements of A and B, and so forth.
The equality procedure must be consistent with eq?. That is, it must be the case that
(eq? x y) => (elt= x y).
Note that this implies that two lists which are eq? are always list=, as well; implementations may exploit this fact to "short-cut" the element-by-element comparisons.
(list= eq?) => #t ; Trivial cases
(list= eq? '(a)) => #t
# first
(first x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(first '(a b c d e f g h i j)) => a
# second
(second x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(second '(a b c d e f g h i j)) => b
# third
(third x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(third '(a b c d e f g h i j)) => c
# fourth
(fourth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(fourth '(a b c d e f g h i j)) => d
# fifth
(fifth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(fifth '(a b c d e f g h i j)) => e
# sixth
(sixth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(sixth '(a b c d e f g h i j)) => f
# seventh
(seventh x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(seventh '(a b c d e f g h i j)) => g
# eighth
(eighth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(eighth '(a b c d e f g h i j)) => h
# ninth
(ninth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(ninth '(a b c d e f g h i j)) => i
# tenth
(tenth x)
Synonyms for `car`, `cadr`, `caddr`, `...`
(tenth '(a b c d e f g h i j)) => j
# car+cdr
(car+cdr pair)
The fundamental pair deconstructor:
(lambda (p) (values (car p) (cdr p)))
# take
(take x i)
`take` returns the first `i` elements of list `x`.
(take '(a b c d e) 2) => (a b)
`x` may be any value -- a proper, circular, or dotted list:
(take '(1 2 3 . d) 2) => (1 2)
(take '(1 2 3 . d) 3) => (1 2 3)
For a legal i, take and drop partition the list in a manner which can be inverted with append:
(append (take x i) (drop x i)) = x
If the argument is a list of non-zero length, `take` is guaranteed to return a freshly-allocated list, even in the case where the entire list is taken, e.g. `(take lis (length lis))`.
# drop
(drop x i)
`drop` returns all but the first `i` elements of list `x`.
(drop '(a b c d e) 2) => (c d e)
`x` may be any value -- a proper, circular, or dotted list:
(drop '(1 2 3 . d) 2) => (3 . d)
(drop '(1 2 3 . d) 3) => d
For a legal i, take and drop partition the list in a manner which can be inverted with append:
(append (take x i) (drop x i)) = x
`drop` is exactly equivalent to performing `i` `cdr` operations on `x`; the returned value shares a common tail with `x`.
# take-right
(take-right flist i)
`take-right` returns the last `i` elements of `flist`.
(take-right '(a b c d e) 2) => (d e)
# drop-right
(drop-right flist i)
`drop-right` returns all but the last `i` elements of `flist`.
(drop-right '(a b c d e) 2) => (a b c)
# take!
(take! x i)
`take!` is a "linear-update" variant of `take`: the procedure is allowed, but not required, to alter the argument list to produce the result.
If x is circular, take! may return a shorter-than-expected list:
(take! (circular-list 1 3 5) 8) => (1 3)
(take! (circular-list 1 3 5) 8) => (1 3 5 1 3 5 1 3)
# drop-right!
(drop-right! flist i)
`drop-right!` is a "linear-update" variant of `drop-right`: the procedure is allowed, but not required, to alter the argument list to produce the result.
# split-at
(split-at x i)
`split-at` splits the list `x` at index `i`, returning a list of the first `i` elements, and the remaining tail. It is equivalent to
(values (take x i) (drop x i))
# split-at!
(split-at! x i)
`split-at!` is the linear-update variant. It is allowed, but not required, to alter the argument list to produce the result.
(split-at '(a b c d e f g h) 3) =>
(a b c)
(d e f g h)
# last
(last pair)
`last` returns the last element of the non-empty, finite list `pair`.
(last '(a b c)) => c
# last-pair
(last-pair pair)
`last-pair` returns the last pair in the non-empty, finite list `pair`.
(last-pair '(a b c)) => (c)
# length+
(length+ clist)
`length+` returns the length of the argument, or `#f` when applied to 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.
# zip
(zip clist1 clist2 ...)
This is equivalent to
(lambda lists (apply map list lists))
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))
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))
# unzip1
(unzip1 list)
`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
(unzip2 list)
`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.
(unzip2 '((1 one) (2 two) (3 three))) =>
(1 2 3)
(one two three)
# unzip3
(unzip3 list)
`unzip3` does the same as `unzip2` for the first three elements of the lists.
# unzip4
(unzip4 list)
`unzip4` does the same as `unzip2` for the first four elements of the lists.
# unzip5
(unzip5 list)
`unzip5` does the same as `unzip2` for the first five elements of the lists.
# count
(count pred clist1 clist2)
`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
# append!
(append! list1 ...)
`append!` is the "linear-update" variant of `append` -- it is allowed, but not required, 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-reverse
(append-reverse 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!
(append-reverse! rev-head tail)
append-reverse! is just the linear-update variant -- it is allowed, but not required, to alter rev-head's cons cells to construct the result.
# concatenate
(concatenate list-of-lists)
This function appends the elements of its argument together. That is, concatenate returns
(apply append list-of-lists)
or, equivalently,
(reduce-right append '() list-of-lists)
The last element of the input list may be any value at all.
# concatenate!
(concatenate! list-of-lists)
`concatenate!` is the linear-update variant of `concatenate`.
# fold
(fold kons knil clist1 clist2 ...)
The fundamental list iterator.
First, consider the single list-parameter case. If `clist1 = (e1 e2 ... en)`, then this procedure returns
(kons en ... (kons e2 (kons e1 knil)) ... )
That is, it obeys the (tail) recursion
(fold kons knil lis) = (fold kons (kons (car lis) knil) (cdr lis))
(fold kons knil '()) = knil
Examples:
(fold + 0 lis) ; Add up the elements of LIS.
(fold cons '() lis) ; Reverse LIS.
(fold cons tail rev-head) ; See APPEND-REVERSE.
;; How many symbols in LIS?
(fold (lambda (x count) (if (symbol? x) (+ count 1) count))
0
lis)
;; Length of the longest string in LIS:
(fold (lambda (s max-len) (max max-len (string-length s)))
0
lis)
If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values:
(fold cons* '() '(a b c) '(1 2 3 4 5)) => (c 3 b 2 a 1)
At least one of the list arguments must be finite.
# fold-right
(fold-right kons knil clist1 clist2 ...)
The fundamental list recursion operator.
First, consider the single list-parameter case. If `clist1 = (e1 e2 ... en)`, then this procedure returns
(kons e1 (kons e2 ... (kons en knil)))
That is, it obeys the recursion
(fold-right kons knil lis) = (kons (car lis) (fold-right kons knil (cdr lis)))
(fold-right kons knil '()) = knil
Examples:
(fold-right cons '() lis) ; Copy LIS.
;; Filter the even numbers out of LIS.
(fold-right (lambda (x l) (if (even? x) (cons x l) l)) '() lis))
If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values:
(fold-right cons* '() '(a b c) '(1 2 3 4 5)) => (a 1 b 2 c 3)
At least one of the list arguments must be finite.
# pair-fold
(pair-fold kons knil clist1 clist2 ...)
Analogous to fold, but kons is applied to successive sublists of the lists, rather than successive elements -- that is, kons is applied to the pairs making up the lists, giving this (tail) recursion:
(pair-fold kons knil lis) = (let ((tail (cdr lis)))
(pair-fold kons (kons lis knil) tail))
(pair-fold kons knil '()) = knil
For finite lists, the kons function may reliably apply set-cdr! to the pairs it is given without altering the sequence of execution.
Example:
;;; Destructively reverse a list.
(pair-fold (lambda (pair tail) (set-cdr! pair tail) pair) '() lis))
At least one of the list arguments must be finite.
# pair-fold-right
(pair-fold-right kons knil clist1 clist2 ...)
Holds the same relationship with fold-right that pair-fold holds with fold. Obeys the recursion
(pair-fold-right kons knil lis) =
(kons lis (pair-fold-right kons knil (cdr lis)))
(pair-fold-right kons knil '()) = knil
Example:
(pair-fold-right cons '() '(a b c)) => ((a b c) (b c) (c))
At least one of the list arguments must be finite.
# reduce
(reduce f ridentity list)
`reduce` is a variant of fold.
`ridentity` should be a "right identity" of the procedure `f` -- that is, for any value `x` acceptable to `f`,
(f x ridentity) = x
`reduce` has the following definition:
If `list = ()`, return `ridentity`;
Otherwise, return `(fold f (car list) (cdr list))`.
...in other words, we compute `(fold f ridentity list)`.
Note that `ridentity` is used only in the empty-list case. You typically use reduce when applying `f` is expensive and you'd like to avoid the extra application incurred when fold applies f to the head of list and the identity value, redundantly producing the same value passed in to f. For example, if f involves searching a file directory or performing a database query, this can be significant. In general, however, fold is useful in many contexts where reduce is not (consider the examples given in the fold definition -- only one of the five folds uses a function with a right identity. The other four may not be performed with reduce).
# reduce-right
(reduce-right f ridentity list)
`reduce-right` is the `fold-right` variant of `reduce`. It obeys the following definition:
(reduce-right f ridentity '()) = ridentity
(reduce-right f ridentity '(e1)) = (f e1 ridentity) = e1
(reduce-right f ridentity '(e1 e2 ...)) =
(f e1 (reduce f ridentity (e2 ...)))
...in other words, we compute (fold-right f ridentity list).
;; Append a bunch of lists together.
;; I.e., (apply append list-of-lists)
(reduce-right append '() list-of-lists)
# unfold
(unfold p f g seed [tail-gen])
`unfold` is best described by its basic recursion:
(unfold p f g seed) =
(if (p seed) (tail-gen seed)
(cons (f seed)
(unfold p f g (g seed))))
- `p` determines when to stop unfolding.
- `f` maps each seed value to the corresponding list element.
- `g` maps each seed value to next seed value.
- `seed` is the "state" value for the unfold.
- `tail-gen` creates the tail of the list; defaults to (lambda (x) '())
In other words, we use g to generate a sequence of seed values
seed, g(seed), g2(seed), g3(seed), ...
These seed values are mapped to list elements by f, producing the elements of the result list in a left-to-right order. P says when to stop.
unfold is the fundamental recursive list constructor, just as fold-right is the fundamental recursive list consumer. While unfold may seem a bit abstract to novice functional programmers, it can be used in a number of ways:
;; List of squares: 1^2 ... 10^2
(unfold (lambda (x) (> x 10))
(lambda (x) (* x x))
(lambda (x) (+ x 1))
1)
(unfold null-list? car cdr lis) ; Copy a proper list.
;; Read current input port into a list of values.
(unfold eof-object? values (lambda (x) (read)) (read))
;; Copy a possibly non-proper list:
(unfold not-pair? car cdr lis
values)
;; Append HEAD onto TAIL:
(unfold null-list? car cdr head
(lambda (x) tail))
Interested functional programmers may enjoy noting that fold-right and unfold are in some sense inverses. That is, given operations knull?, kar, kdr, kons, and knil satisfying
(kons (kar x) (kdr x)) = x and (knull? knil) = #t
then
(fold-right kons knil (unfold knull? kar kdr x)) = x
and
(unfold knull? kar kdr (fold-right kons knil x)) = x.
This combinator sometimes is called an "anamorphism;" when an explicit tail-gen procedure is supplied, it is called an "apomorphism."
# unfold-right
(unfold-right p f g seed [tail])
unfold-right constructs a list with the following loop:
(let lp ((seed seed) (lis tail))
(if (p seed) lis
(lp (g seed)
(cons (f seed) lis))))
- `p` determines when to stop unfolding.
- `f` maps each seed value to the corresponding list element.
- `g` maps each seed value to next seed value.
- `seed` is the "state" value for the unfold.
- `tail` is the list terminator; defaults to '().
In other words, we use g to generate a sequence of seed values
seed, g(seed), g2(seed), g3(seed), ...
These seed values are mapped to list elements by f, producing the elements of the result list in a right-to-left order. P says when to stop.
unfold-right is the fundamental iterative list constructor, just as fold is the fundamental iterative list consumer. While unfold-right may seem a bit abstract to novice functional programmers, it can be used in a number of ways:
;; List of squares: 1^2 ... 10^2
(unfold-right zero?
(lambda (x) (* x x))
(lambda (x) (- x 1))
10)
;; Reverse a proper list.
(unfold-right null-list? car cdr lis)
;; Read current input port into a list of values.
(unfold-right eof-object? values (lambda (x) (read)) (read))
;; (append-reverse rev-head tail)
(unfold-right null-list? car cdr rev-head tail)
Interested functional programmers may enjoy noting that fold and unfold-right are in some sense inverses. That is, given operations knull?, kar, kdr, kons, and knil satisfying
(kons (kar x) (kdr x)) = x and (knull? knil) = #t
then
(fold kons knil (unfold-right knull? kar kdr x)) = x
and
(unfold-right knull? kar kdr (fold kons knil x)) = x.
This combinator presumably has some pretentious mathematical name; interested readers are invited to communicate it to the author.
# append-map
(append-map f clist1 clist2 ...)
Equivalent to
(apply append (map f clist1 clist2 ...))
Map `f` over the elements of the lists, just as in the `map` function. However, the results of the applications are appended together to make the final result. `append-map` uses `append` to append the results together.
The dynamic order in which the various applications of f are made is not specified.
# append-map!
(append-map! f clist1 clist2 ...)
Equivalent to
(apply append! (map f clist1 clist2 ...))
Map `f` over the elements of the lists, just as in the `map` function. However, the results of the applications are appended together to make the final result. `append-map!` uses `append!` to append the results together.
The dynamic order in which the various applications of f are made is not specified.
Example:
(append-map! (lambda (x) (list x (- x))) '(1 3 8))
=> (1 -1 3 -3 8 -8)
At least one of the list arguments must be finite.
# map!
(map! f list1 clist2 ...)
Linear-update variant of `map` -- `map!` is allowed, but not required, to alter the cons cells of list1 to construct the result list.
The dynamic order in which the various applications of f are made is not specified. In the n-ary case, clist2, clist3, ... must have at least as many elements as list1.
# pair-for-each
(pair-for-each f clist1 clist2 ...)
Like for-each, but f is applied to successive sublists of the argument lists. That is, f is applied to the cons cells of the lists, rather than the lists' elements. These applications occur in left-to-right order.
The f procedure may reliably apply set-cdr! to the pairs it is given without altering the sequence of execution.
(pair-for-each (lambda (pair) (display pair) (newline)) '(a b c)) ==>
(a b c)
(b c)
(c)
At least one of the list arguments must be finite.
# filter-map
(filter-map f clist1 clist2 ...)
Like `map`, but only true values are saved.
(filter-map (lambda (x) (and (number? x) (* x x))) '(a 1 b 3 c 7))
=> (1 9 49)
The dynamic order in which the various applications of f are made is not specified.
At least one of the list arguments must be finite.
# map-in-order
(map-in-order f clist1 clist2 ...)
A variant of the map procedure that guarantees to apply f across the elements of the listi arguments in a left-to-right order. This is useful for mapping procedures that both have side effects and return useful values.
At least one of the list arguments must be finite.
# filter
(filter pred list)
Return all the elements of list that satisfy predicate pred. The list is not disordered -- elements that appear in the result list occur in the same order as they occur in the argument list. The returned list may share a common tail with the argument list. The dynamic order in which the various applications of pred are made is not specified.
(filter even? '(0 7 8 8 43 -4)) => (0 8 8 -4)
# partition
(partition pred list)
Partitions the elements of list with predicate pred, and returns two values: the list of in-elements and the list of out-elements. The list is not disordered -- elements occur in the result lists in the same order as they occur in the argument list. The dynamic order in which the various applications of pred are made is not specified. One of the returned lists may share a common tail with the argument list.
(partition symbol? '(one 2 3 four five 6)) =>
(one four five)
(2 3 6)
# remove
(remove pred list)
Returns list without the elements that satisfy predicate pred:
(lambda (pred list) (filter (lambda (x) (not (pred x))) list))
The list is not disordered -- elements that appear in the result list occur in the same order as they occur in the argument list. The returned list may share a common tail with the argument list. The dynamic order in which the various applications of pred are made is not specified.
(remove even? '(0 7 8 8 43 -4)) => (7 43)
# filter!
(filter! pred list)
Linear-update variant of `filter`. This procedure is allowed, but not required, to alter the cons cells in the argument list to construct the result lists.
# partition!
(partition! pred list)
Linear-update variant of `partition`. This procedure is allowed, but not required, to alter the cons cells in the argument list to construct the result lists.
# remove!
(remove! pred list)
Linear-update variant of `remove`. This procedure is allowed, but not required, to alter the cons cells in the argument list to construct the result lists.
# find
# find-tail
# any
# every
# list-index
# take-while
# drop-while
# take-while!
# span
# break
# span!
# break!
# delete
# delete!
# alist-cons
# alist-copy
# delete-duplicates
# delete-duplicates!
# alist-delete
# alist-delete!
# reverse!
# lset<=
# lset=
# lset-adjoin
# lset-union
# lset-intersection
# lset-difference
# lset-xor
# lset-diff+intersection
# lset-union!
# lset-intersection!
# lset-difference!
# lset-xor!