SRFI 133: Vector Library (R7RS-compatible)
******************************************

SRFI 133: Vector Library (R7RS-compatible)
(https://srfi.schemers.org/srfi-133/srfi-133.html)

   _[2025-04-22 Tue 05:19]_

— The Detailed Node Listing —

Procedures

1 Title
*******

Vector Library (R7RS-compatible)

2 Author
********

John Cowan (based on SRFI 43 by Taylor Campbell)

3 Issues
********

None at this time.

4 Status
********

This SRFI is currently in _final_ status.  Here is an explanation
(https://srfi.schemers.org/srfi-process.html) of each status that a SRFI
can hold.  To provide input on this SRFI, please send email to =
=‘srfi-133@ ==nospam==srfi.schemers.org’
<srfi+minus+133+at+srfi+dotschemers+dot+org>.  To subscribe to the list,
follow these instructions
(http://srfi.schemers.org/srfi-list-subscribe.html).  You can access
previous messages via the mailing list archive
(https://srfi-email.schemers.org/srfi-133).

   • Received: 2015-12-15
   • 60-day deadline: 2016-02-14
   • Draft #1 published: 2015-12-16
   • Draft #2 published: 2016-01-24
   • Draft #3 published: 2016-01-31
   • Draft #4 published: 2016-03-12
   • Finalized: 2016-03-20
   • Revised to fix errata:
        • 2016-04-01 (Fixed description of ‘vector-unfold!’)
        • 2016-08-10 (Fixed typos.)
        • 2016-09-02 (Changed order of arguments to ‘vector-cumulate’
          from ‘(vector-cumulate f vec knil)’ to ‘(vector-cumulate f
          knil vec)’ to match the argument order of ‘vector-fold’.)
        • 2017-06-05 (Added second return type of ‘vector-partition’.)
        • 2018-07-04 (Removed requirement that ‘elt’?= argument be
          consistent with ‘eq?’.)
        • 2018-10-27 (Fixed typos.)
        • 2024-01-26 (Fixed definition of _end_ notation.
          Added missing constraint on length of first argument of
          ‘vector-map!’.  Clarified the second return
          value of ‘vector-partition’ in the
          case that all elements satisfy _pred?_.)

   *Post-finalization note*: The finalized version of this SRFI required
the equality operator used by the ‘vector=’ procedure to be consistent
with ‘eq?’.  However, ‘=’ is not consistent with ‘eq?’ in a Scheme which
provides NaN values and IEEE semantics for them, as ‘(eq? +nan.0
+nan.0)’ may return either ‘#t’ or ‘#f’ but ‘(’ +nan.0 +nan.0)= must
return ‘#f. = This means that the expected semantics of ==’ when used
with ‘vector=’ are violated.  Therefore, the requirement for consistency
has been removed from this version, and the sample implementation
adjusted accordingly.

5 Abstract
**********

This SRFI proposes a comprehensive library of vector operations
accompanied by a freely available and complete reference implementation.
The reference implementation is unencumbered by copyright, and useable
with no modifications on any Scheme system that is
R5RS-compliant.  It also provides several hooks for
implementation-specific optimization as well.

6 Rationale
***********

R5RS provides very few list-processing procedures, for which
reason SRFI 1 exists.  However, see R5RS provides
even fewer vector operations — while it provides mapping, appending, et
cetera operations for lists, it specifies only nine vector manipulation
operations:

   • = =See ‘vector?’.
   • = =See ‘make-vector’.
   • = =See ‘vector’.
   • = =See ‘vector-length’.
   • = =See ‘vector-ref’.
   • = =See ‘vector-set!’.
   • = =See ‘vector->list’.
   • = =See ‘list->vector’.
   • = =See ‘vector-fill!’.

   R7RS-small added support for _start_ and _end_ arguments to
‘vector->list’, ‘list->vector’ and ‘vector-fill!’.  It also provided
seven additional vector procedures, bringing vectors and lists to
approximate parity:

   • = =See ‘vector-copy’.
   • = =See ‘vector-copy!’.
   • = =See ‘vector-append’.
   • = =See ‘vector-map’.
   • = =See ‘vector-for-each’.
   • = =See ‘vector->string’.
   • = =See ‘string->vector’.

   SRFI 43 standardized more vector procedures, all of
which are included in this SRFI.  Unfortunately, R7RS-small and SRFI 43
placed irreconcileable requirements on the procedures invoked by
‘vector-map’ and ‘vector-for-each’.  This SRFI resolves that issue by
changing these SRFI 43 procedures as well as ‘vector-map!’,
‘vector-fold’, ‘vector-fold-right’, and ‘vector-count’ to leave out the
‘index’ argument that is passed under SRFI 43’s definition.

   In addition, the version of ‘vector-copy’ in this SRFI does not
require support for a ‘fill’ argument, which makes it equivalent to the
R7RS-small definition.

   This SRFI also provides the following new procedures (some from
Python, some from other sources):

   • = =See ‘vector-unfold!’.
   • = =See ‘vector-unfold-right!’.
   • = =See ‘vector-append-subvectors’.
   • = =See ‘vector-cumulate’.
   • = =See ‘vector-partition’.

   It should be noted that no vector sorting procedures are provided by
this SRFI, because there already are several SRFIs for that purpose.

7 R7RS-small Support
********************

Here is a list of the procedures provided by this package that are also
provided in R7RS-small.

   • make-vector
   • vector
   • vector-copy
   • vector-append
   • vector?.
   • vector-ref
   • vector-length
   • vector-map
   • vector-for-each
   • vector->list.
   • list->vector.
   • vector->string.
   • string->vector.

8 Procedures
************

In this section containing specifications of procedures, the following
notation is used to specify parameters and return values:

(f arg _{1} arg _{2} ...) -> something
     Indicates a function = ‘/=f=/ takes the parameters = =/=arg
     =_{=1’}= arg ‘_{=2’}= ...=/ and returns a value of the type =
     ‘/=something=/. If = =/=something=/ is =unspecified’, then = =/=f=/
     returns a single implementation-dependent value; this SRFI does not
     specify what it returns, and in order to write portable code, the
     return value should be ignored.

vec
     The argument in this place must be a vector, i.e.  it must satisfy
     the predicate = =See ‘vector?’.

i, j, start, size
     The argument in this place must be an exact nonnegative integer,
     i.e.  it must satisfy the predicates ‘exact?’, ‘integer?’ and
     either ‘zero?’ or ‘positive?’.  The third case of it indicates the
     index at which traversal begins; the fourth case of it indicates
     the size of a vector.

end
     The argument in this place must be an exact nonnegative integer,
     i.e.  it must satisfy the predicates ‘exact?’, ‘integer?’ and
     either ‘zero?’ or ‘positive?’.  This indicates the index directly
     before which traversal will stop — processing will occur until the
     the index of the vector is = =/=end=/.  It is the closed right side
     of a range.

f
     The argument in this place must be a function of one or more
     arguments, which returns (except as noted otherwise) exactly one
     value.

pred?
     The argument in this place must be a function of one or more
     arguments that returns one value, which is treated as a boolean.

x, y, z, seed, knil, fill, key, value
     The argument in this place may be any Scheme value.

[something]
     Indicates that = =/=something=/ is an optional argument; it needn’t
     necessarily be applied.  = =/=Something=/ needn’t necessarily be
     one thing; for example, this usage of it is perfectly valid:

     = [start [end]] =

     and is indeed used quite often.

something ...
     Indicates that zero or more = =/=something=/s are allowed to be
     arguments.

something _{1} something _{2} ...
     Indicates that at least one = =/=something=/ must be arguments.

something _{1} something _{2} ... something _{n}
     Exactly equivalent to the previous argument notation, but this also
     indicates that = =/=n=/ will be used later in the procedure
     description.

   It should be noted that all of the procedures that iterate across
multiple vectors in parallel stop iterating and produce the final result
when the end of the shortest vector is reached.  The sole exception is =
‘[[vector-eq][=vector==]], which automatically returns =#f’ if the
vectors’ lengths vary.

8.1 Constructors
================

(make-vector _size_ [ /fill/]) -> vector
     [ see _R7RS-small_] Creates and returns a vector of
     size = =/=size=/.  If _fill_ is specified, all the elements of the
     vector are initialized to _fill_.  Otherwise, their contents are
     indeterminate.

     Example:

     = (make-vector 5 3) =
     = #(3 3 3 3 3) =

(vector _x ..._) -> vector
     [ see _R7RS-small_] Creates and returns a vector
     whose elements are = =/=x ...=/.

     Example:

     = (vector 0 1 2 3 4) =
     = #(0 1 2 3 4) =

(vector-unfold _f length initial-seed ..._) -> vector
     The fundamental vector constructor.  Creates a vector whose length
     is = ‘/=length=/ and iterates across each index = =/=k=/ between
     =0’ and = ‘/=length=/, applying = =/=f=/ at each iteration to the
     current index and current seeds, in that order, to receive =
     =/=n=/’ + 1= values: first, the element to put in the = ‘/=k=/th
     slot of the new vector and = =/=n=/ new seeds for the next
     iteration. It is an error for the number of seeds to vary between
     iterations. Note that the termination condition is different from
     the =unfold’ procedure of SRFI 1.

     Examples:

     = (vector-unfold (λ (i x) (values x (- x 1)))=
     ‘10 0) =\\ = #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9) =\\ \\ Construct a
     vector of the sequence of integers in the range [0, = =/=n=/).\\ =
     (vector-unfold values =’ ‘/=n=/’) ‘\\ = #(0 1 2 ... =/=n-2=/’
     ‘/=n-1=/’) ‘\\ \\ Copy = =/=vector=/.\\ \\ = (vector-unfold (λ (i)
     (vector-ref =/=vector=/’ i))=
     ‘(vector-length =/=vector=/’)) =

(vector-unfold-right _f length initial-seed ..._) -> vector
     Like = ‘[[vector-unfold][=vector-unfold=]], but it uses = =/=f=/ to
     generate elements from right-to-left, rather than left-to-right.
     The first index used is /length/ - 1. Note that the termination
     condition is different from the =unfold-right’ procedure of
     SRFI 1.

     Examples:

     Construct a vector of pairs of non-negative integers whose values
     sum to 4.

     = (vector-unfold-right (λ (i x) (values (cons i x) (+ x 1))) 5 0)
     ‘\\ = #((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0)) =\\ \\ Reverse =
     =/=vector=/.\\ \\ = (vector-unfold-right (λ (i x) (values
     (vector-ref =/=vector=/’ x) (+ x 1)))=
     ‘(vector-length =/=vector=/’)=
     =0) =

(vector-copy _vec_ [ _start_ [ /end/]]) -> vector
     [ see _R7RS-small_] Allocates a new vector whose
     length is = ‘/=end=/’ - ‘/=start=/ and fills it with elements from
     = =/=vec=/, taking elements from = =/=vec=/ starting at index =
     =/=start=/ and stopping at index = =/=end=/. = =/=Start=/ defaults
     to =0’ and = ‘/=end=/ defaults to the value of =(
     =[[vector-length][=vector-length=]]’ ‘/=vec=/’)=.  SRFI 43 provides
     an optional ‘fill’ argument to supply values if ‘end’ is greater
     than the length of ‘vec’.  Neither R7RS-small nor this SRFI
     requires support for this argument.

     Examples:

     = (vector-copy ’#(a b c d e f g h i)) =
     = #(a b c d e f g h i) =

     = (vector-copy ’#(a b c d e f g h i) 6) =
     = #(g h i) =

     = (vector-copy ’#(a b c d e f g h i) 3 6) =
     = #(d e f) =

(vector-reverse-copy _vec_ [ _start_ [ /end/]]) -> vector
     Like = =See ‘vector-copy’, but it copies the
     elements in the reverse order from = =/=vec=/.

     Example:

     = (vector-reverse-copy ’#(5 4 3 2 1 0) 1 5) =
     = #(1 2 3 4) =

(vector-append _vec ..._) -> vector
     [ see _R7RS-small_] Returns a newly allocated vector
     that contains all elements in order from the subsequent locations
     in = =/=vec ...=/.

     Examples:

     = (vector-append ’#(x) ’#(y)) =
     = #(x y) =

     = (vector-append ’#(a) ’#(b c d)) =
     = #(a b c d) =

     = (vector-append ’#(a #(b)) ’#(#(c))) =
     = #(a #(b) #(c)) =

(vector-concatenate _list-of-vectors_) -> vector
     Appends each vector in = ‘/=list-of-vectors=/. This is equivalent
     to:\\ \\ = (apply =[[vector-append][=vector-append=]]’
     ‘/=list-of-vectors=/’) =

     However, it may be implemented better.

     Example:

     = (vector-concatenate ’(#(a b) #(c d))) =
     = #(a b c d) =

(vector-append-subvectors [ _vec start end] ..._) -> vector
     Returns a vector that contains every element of each _vec_ from
     _start_ to _end_ in the specified order.  This procedure is a
     generalization of ‘vector-append’.

     Example:

     = (vector-append-subvectors ’#(a b c d e) 0 2 ’#(f g h i j) 2 4) =
     = #(a b h i) =

8.2 Predicates
==============

(vector? _x_) -> boolean
     [ see _R7RS-small_] Disjoint type predicate for
     vectors: this returns ‘#t’ if = ‘/=x=/ is a vector, and =#f’ if
     otherwise.

     Examples:

     = (vector?  ’#(a b c)) =
     = #t =

     = (vector?  ’(a b c)) =
     = #f =

     = (vector?  #t) =
     = #f =

     = (vector?  ’#()) =
     = #t =

     = (vector?  ’()) =
     = #f =

(vector-empty? _vec_) -> boolean
     Returns ‘#t’ if = ‘/=vec=/ is empty, i.e. its length is =0’, and
     ‘#f’ if not.

     Examples:

     = (vector-empty?  ’#(a)) =
     = #f =

     = (vector-empty?  ’#(())) =
     = #f =

     = (vector-empty?  ’#(#())) =
     = #f =

     = (vector-empty?  ’#()) =
     = #t =

(vector= _elt=? vec ..._) -> boolean
     Vector structure comparator, generalized across user-specified
     element comparators.  Vectors = ‘/=a=/ and = =/=b=/ are considered
     equal by =vector=’ iff their lengths are the same, and for each
     respective element = ‘/=E=/’ ‘_{=a’} and = ‘/=E=/’ ‘_{=b’}, ‘(
     =/=elt’?  E=/= ‘_{=a’}= ‘/=E=/’ ‘_{=b’}=)= returns a true value.  =
     ‘/=Elt’?=/ is always applied to two arguments.

     If there are only zero or one vector arguments, ‘#t’ is
     automatically returned.  The dynamic order in which comparisons of
     elements and of vectors are performed is left completely
     unspecified; do not rely on a particular order.

     Examples:

     = (vector= eq?  ’#(a b c d) ’#(a b c d)) ‘\\ = #t =\\ \\ = (vector’
     eq?  ’#(a b c d) ’#(a b d c)) ‘\\ = #f =\\ \\ = (vector’ = ’#(1 2 3
     4 5) ’#(1 2 3 4)) ‘\\ = #f =\\ \\ = (vector’ = ’#(1 2 3 4) ’#(1 2 3
     4)) ‘\\ = #t =\\ \\ The two trivial cases.\\ \\ = (vector’ eq?)
     ‘\\ = #t =\\ \\ = (vector’ eq?  ’#(a)) ‘\\ = #t =\\ \\ Note the
     fact that we don't use vector literals in the next two --- it is
     unspecified whether or not literal vectors with the same external
     representation are =eq?’.

     = (vector= eq?  (vector (vector ’a)) (vector (vector ’a))) ‘\\ = #f
     =\\ \\ = (vector’ equal?  (vector (vector ’a)) (vector (vector
     ’a))) =
     = #t =

8.3 Selectors
=============

(vector-ref _vec i_) -> value
     [ see _R7RS-small_] Vector element dereferencing:
     returns the value that the location in = ‘/=vec=/ at = =/=i=/ is
     mapped to in the store. Indexing is based on zero. = =/=I=/ must be
     within the range [0, =( =[[vector-length][=vector-length=]]’
     ‘/=vec=/’)=).

     Example:

     = (vector-ref ’#(a b c d) 2) =
     = c =

(vector-length _vec_) -> exact nonnegative integer
     [ see _R7RS-small_] Returns the length of =
     =/=vec=/, the number of locations reachable from = =/=vec=/.  (The
     careful word ’reachable’ is used to allow for ’vector slices,’
     whereby = =/=vec=/ refers to a larger vector that contains more
     locations that are unreachable from = =/=vec=/.  This SRFI does not
     define vector slices, but later SRFIs may.)

     Example:

     = (vector-length ’#(a b c)) =
     = 3 =

8.4 Iteration
=============

(vector-fold _kons knil vec _{1} vec _{2} ..._) -> value
     The fundamental vector iterator.  = ‘/=Kons=/ is iterated over each
     value in all of the vectors, stopping at the end of the shortest; =
     =/=kons=/ is applied as = ( =/=kons=/’ ‘/=state=/’ (
     ‘[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=1’}/= ‘/=i=/’) (
     ‘[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=2’}/= ‘/=i=/’) ...) =
     where = ‘/=state=/ is the current state value --- the current state
     value begins with = =/=knil=/, and becomes whatever = =/=kons=/
     returned on the previous iteration ---, and = =/=i=/ is the current
     index.\\ \\ The iteration is strictly left-to-right.\\ \\
     Examples:\\ \\ Find the longest string's length in =
     =/=vector-of-strings=/.\\ = (vector-fold (λ (len str) (max
     (string-length str) len))’
     ‘0 =/=vector-of-strings=/’) ‘\\ \\ Produce a list of the reversed
     elements of = =/=vec=/.\\ = (vector-fold (λ (tail elt) (cons elt
     tail))’
     ‘'() =/=vec=/’) ‘\\ \\ Count the number of even numbers in =
     =/=vec=/.\\ = (vector-fold (λ (counter n)’
     ‘(if (even? n) (+ counter 1) counter))’
     ‘0 =/=vec=/’) =

(vector-fold-right _kons knil vec _{1} vec _{2} ..._) -> value
     Similar to = ‘[[vector-fold][=vector-fold=]], but it iterates right
     to left instead of left to right.\\ \\ Example:\\ \\ Convert a
     vector to a list.\\ = (vector-fold-right (λ (tail elt) (cons elt
     tail))’
     =’() ’#(a b c d)) =
     = (a b c d) =

(vector-map _f vec _{1} vec _{2} ..._) -> vector
     [ see _R7RS-small_] Constructs a new vector of the
     shortest size of the vector arguments.  Each element at index =
     ‘/=i=/ of the new vector is mapped from the old vectors by =(
     =/=f=/’ ( ‘[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=1’}/= ‘/=i=/’)
     ( ‘[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=2’}/= ‘/=i=/’) ...)=.
     The dynamic order of application of = ‘/=f=/ is unspecified.\\ \\
     Examples:\\ \\ = (vector-map (λ (x) (* x x))’
     ‘( =[[vector-unfold][=vector-unfold=]]’ (λ (i x) (values x (+ x
     1))) 4 1)) ‘\\ = #(1 4 9 16) =\\ \\ = (vector-map (λ (x y) (* x
     y))’
     ‘( =[[vector-unfold][=vector-unfold=]]’ (λ (x) (values x (+ x 1)))
     5 1)=
     ‘( =[[vector-unfold][=vector-unfold=]]’ (λ (x) (values x (- x 1)))
     5 5)) ‘\\ = #(5 8 9 8 5) =\\ \\ = (let ((count 0)) =\\ =
     (vector-map (λ (ignored-elt) =\\ = (set! count (+ count 1)) =\\ =
     count) =\\ = '#(a b))) =\\ = #(1 2) =/=OR=/’ #(2 1) =

(vector-map! _f vec _{1} vec _{2} ..._) -> unspecified
     Similar to = ‘[[vector-map][=vector-map=]], but rather than mapping
     the new elements into a new vector, the new mapped elements are
     destructively inserted into = =/=vec =_{=1’}/.  Again, the dynamic
     order of application of = ‘/=f=/ unspecified, so it is dangerous
     for = =/=f=/ to apply either = =[[vector-ref][=vector-ref=]] or =
     =[[vector-set-bang][=vector-set!=]] to = =/=vec =_{=1’}/ in =
     ‘/=f=/. It is an error if = =/=vec =_{=1’}/ contains more elements
     than any other = =/=vec=/.

(vector-for-each _f vec _{1} vec _{2} ..._) -> unspecified
     [ see _R7RS-small_] Simple vector iterator: applies
     = ‘/=f=/ to the corresponding list of parallel elements from =
     =/=vec =_{=1’}= vec ‘_{=2’}/= ...= in the range [0, = =/=length=/),
     where = =/=length=/ is the length of the smallest vector argument
     passed, In contrast with = =See ‘vector-map’, =
     =/=f=/ is reliably applied to each subsequent element, starting at
     index 0, in the vectors.

     Example:

     = (vector-for-each (λ (x) (display x) (newline)) =
     = ’#("foo" "bar" "baz" "quux" "zot")) =
     Displays:

          foo
          bar
          baz
          quux
          zot

(vector-count _pred? vec _{1} vec _{2} ..._) -> exact nonnegative integer
     Counts the number of parallel elements in the vectors that satisfy
     = =/=pred?=/, which is applied, for each index = =/=i=/ in the
     range [0, = =/=length=/) where = =/=length=/ is the length of the
     smallest vector argument, to each parallel element in the vectors,
     in order.

     Examples:

     = (vector-count even?  ’#(3 1 4 1 5 9 2 5 6)) =
     = 3 =

     = (vector-count < ’#(1 3 6 9) ’#(2 4 6 8 10 12)) =
     = 2 =

(vector-cumulate _f knil vec_) -> vector
     Returns a newly allocated vector = ‘/=new=/ with the same length as
     = =/=vec=/. Each element /i/ of /new/ is set to the result of
     invoking = =/=f=/ on /=new’ _{i-1}/ and _‘vec’ _{i}_, except that
     for the first call on _f_, the first argument is _knil_.  The _new_
     vector is returned.

     Note that the order of arguments to ‘vector-cumulate’ was changed
     by ‘errata-3’ on 2016-09-02.

     Example:

     = (vector-cumulate + 0 ’#(3 1 4 1 5 9 2 5 6)) =
     = #(3 4 8 9 14 23 25 30 36) =

8.5 Searching
=============

(vector-index _pred? vec _{1} vec _{2} ..._) -> exact nonnegative integer or #f
     Finds & returns the index of the first elements in = ‘/=vec
     =_{=1’}= vec ‘_{=2’}= ...=/ that satisfy = ‘/=pred?=/. If no
     matching element is found by the end of the shortest vector, =#f’
     is returned.

     Examples:

     = (vector-index even?  ’#(3 1 4 1 5 9)) =
     = 2 =

     = (vector-index < ’#(3 1 4 1 5 9 2 5 6) ’#(2 7 1 8 2)) =
     = 1 =

     = (vector-index = ’#(3 1 4 1 5 9 2 5 6) ’#(2 7 1 8 2)) =
     = #f =

(vector-index-right _pred? vec _{1} vec _{2} ..._) -> exact nonnegative integer or #f
     Like = =See ‘vector-index’, but it searches
     right-to-left, rather than left-to-right, and all of the vectors
     _must_ have the same length.

(vector-skip _pred? vec _{1} vec _{2} ..._) -> exact nonnegative integer or #f
     Finds & returns the index of the first elements in = ‘/=vec
     =_{=1’}= vec ‘_{=2’}= ...=/ that do _not_ satisfy = ‘/=pred?=/. If
     all the values in the vectors satisfy = =/=pred?=/ until the end of
     the shortest vector, this returns =#f’.  This is equivalent to:

     = ( ‘[[vector-index][=vector-index=]]’ (λ (x ‘_{/=1=/}’ x
     ‘_{/=2=/}’ ‘/’...=/=) (not ( ‘/=pred?=/’ x ‘_{/=1=/}’ x ‘_{/=1=/}’
     ‘/’...=/=)))=
     /=vec ‘_{=1’}= vec ‘_{=2’}= ...=/=) =

     Example:

     = (vector-skip number?  ’#(1 2 a b 3 4 c d)) =
     = 2 =

(vector-skip-right _pred? vec _{1} vec _{2} ..._) -> exact nonnegative integer or #f
     Like = ‘[[vector-skip][=vector-skip=]], but it searches for a
     non-matching element right-to-left, rather than left-to-right, and
     it is an error if all of the vectors do not have the same length.
     This is equivalent to:\\ \\ = (
     =[[vector-index][=vector-index-right=]]’ (λ (x ‘_{/=1=/}’ x
     ‘_{/=2=/}’ ‘/’...=/=) (not ( ‘/=pred?=/’ x ‘_{/=1=/}’ x ‘_{/=1=/}’
     ‘/’...=/=)))=
     /=vec ‘_{=1’}= vec ‘_{=2’}= ...=/=) =

(vector-binary-search _vec value cmp_) -> exact nonnegative integer or #f
     Similar to = ‘[[vector-index][=vector-index=]] and =
     =[[vector-index-right][=vector-index-right=]], but instead of
     searching left to right or right to left, this performs a binary
     search. If there is more than one element of /vec/ that matches
     /value/ in the sense of /cmp/, =vector-binary-search’ may return
     the index of any of them.

     = ‘/=cmp=/ should be a procedure of two arguments and return a
     negative integer, which indicates that its first argument is less
     than its second, zero, which indicates that they are equal, or a
     positive integer, which indicates that the first argument is
     greater than the second argument. An example = =/=cmp=/ might be:\\
     \\ = (λ ( =/=char =_{=1’}/= ‘/=char =_{=2’}/=) ‘\\ = (cond ((char<?
     =/=char =_{=1’}= char ‘_{=2’}/=) -1) ‘\\ = ((char’?  ‘/=char
     =_{=1’}= char ‘_{=2’}/=) 0) =
     = (else 1))) =

(vector-any _pred? vec _{1} vec _{2} ..._) -> value or #f
     Finds the first set of elements in parallel from = ‘/=vec =_{=1’}=
     vec ‘_{=2’}= ...=/ for which = ‘/=pred?=/ returns a true value. If
     such a parallel set of elements exists, =vector-any’ returns the
     value that = =/=pred?=/ returned for that set of elements.  The
     iteration is strictly left-to-right.

(vector-every _pred? vec _{1} vec _{2} ..._) -> value or #f
     If, for every index = ‘/=i=/ between 0 and the length of the
     shortest vector argument, the set of elements =(
     =[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=1’}/= ‘/=i=/’) (
     ‘[[vector-ref][=vector-ref=]]’ ‘/=vec =_{=2’}/= ‘/=i=/’) ...=
     satisfies = ‘/=pred?=/, =vector-every’ returns the value that =
     =/=pred?=/ returned for the last set of elements, at the last index
     of the shortest vector.  The iteration is strictly left-to-right.

(vector-partition _pred? vec_) -> vector and integer
     A vector the same size as = =/=vec=/ is newly allocated and filled
     with all the elements of = =/=vec=/ that satisfy = =/=pred?=/ in
     their original order followed by all the elements that do not
     satisfy = =/=pred?=/, also in their original order.

     Two values are returned, the newly allocated vector and the number
     of elements satisfy = =/=pred?=/.

8.6 Mutators
============

(vector-set! _vec i value_) -> unspecified
     [ see _R7RS-small_] Assigns the contents of the
     location at = =/=i=/ in = =/=vec=/ to = =/=value=/.

(vector-swap! _vec i j_) -> unspecified
     Swaps or exchanges the values of the locations in = =/=vec=/ at =
     =/=i=/ & = =/=j=/.

(vector-fill! _vec fill_ [ _start_ [ /end/]]) -> unspecified
     [ see _R7RS-small_] Assigns the value of every
     location in = ‘/=vec=/ between = =/=start=/, which defaults to =0’
     and = =/=end=/, which defaults to the length of = =/=vec=/, to =
     =/=fill=/.

(vector-reverse! _vec_ [ _start_ [ /end/]]) -> unspecified
     Destructively reverses the contents of the sequence of locations in
     = ‘/=vec=/ between = =/=start=/ and = =/=end=/. = =/=Start=/
     defaults to =0’ and = =/=end=/ defaults to the length of =
     =/=vec=/.  Note that this does not deeply reverse.

(vector-copy! _to at from_ [ _start_ [ /end/]]) -> unspecified
     [ see _R7RS-small_] Copies the elements of vector =
     =/=from=/ between = =/=start=/ and = =/=end=/ to vector = =/=to=/,
     starting at = =/=at=/.  The order in which elements are copied is
     unspecified, except that if the source and destination overlap,
     copying takes place as if the source is first copied into a
     temporary vector and then into the destination.  This can be
     achieved without allocating storage by making sure to copy in the
     correct direction in such circumstances.

(vector-reverse-copy! _to at from_ [ _start_ [ /end/]]) -> unspecified
     Like = =See ‘vector-copy!’, but the elements
     appear in = =/=to=/ in reverse order.

(vector-unfold! _f vec start end initial-seed ..._) -> unspecified
     Like = =See ‘vector-unfold’, but the elements are
     copied into the vector _vec_ starting at element _start_ rather
     than into a newly allocated vector.  Terminates when _end-start_
     elements have been generated.

(vector-unfold-right! _f vec start end initial-seed ..._) -> unspecified
     Like = =See ‘vector-unfold!’, but the
     elements are copied in reverse order into the vector _vec_ starting
     at the index preceding _end_.

8.7 Conversion
==============

(vector->list _vec_ [ _start_ [ /end/]]) -> proper-list
     [ see _R7RS-small_] Creates a list containing the
     elements in = ‘/=vec=/ between = =/=start=/, which defaults to =0’,
     and = =/=end=/, which defaults to the length of = =/=vec=/.

(reverse-vector->list _vec_ [ _start_ [ /end/]]) -> proper-list
     Like = =See ‘vector->list’, but the resulting
     list contains the elements in reverse of = =/=vec=/.

(list->vector _proper-list_) -> vector
     [ see _R7RS-small_] Creates a vector of elements
     from = =/=proper-list=/.

(reverse-list->vector _proper-list_) -> vector
     Like = =See ‘list->vector’, but the resulting
     vector contains the elements in reverse of = =/=proper-list=/.

(string->vector _string_ [ _start_ [ /end/]]) -> vector
     [ see _R7RS-small_] Creates a vector containing the
     elements in = ‘/=string=/ between = =/=start=/, which defaults to
     =0’, and = =/=end=/, which defaults to the length of = =/=string=/.

(vector->string _vec_ [ _start_ [ /end/]]) -> string
     [ see _R7RS-small_] Creates a string containing the
     elements in = ‘/=vec=/ between = =/=start=/, which defaults to =0’,
     and = =/=end=/, which defaults to the length of = =/=vec=/.  It is
     an error if the elements are not characters.

9 Sample Implementation
***********************

The sample implementation is in the repository of this SRFI.  It has
only one non-R5RS dependency: SRFI 23.’s ‘error’
procedure, which is also provided by R7RS-small.  It is in the public
domain, or alternatively under the same copyright as this SRFI.  The
following files are provided:

   • ‘vectors-impl.scm’ - a modified version of the implementation of
     SRFI 43
   • ‘vectors.scm’ - a Chicken library showing what to export for an
     R5RS implementation
   • ‘vectors.sld’ - an R7RS library that excludes what R7RS-small
     already provides
   • ‘vectors-test.scm’ - tests using the Chicken test egg (also
     available on Chibi)

11 Acknowledgements
*******************

These acknowledgements are copied from SRFI 43.

   Thanks to Olin Shivers for his wonderfully complete list
and string packages; to all the members of the
‘#scheme’ IRC channel (http://scheme-irc.webhop.org/) on Freenode
(http://www.freenode.net/) who nitpicked a great deal, but also helped
quite a lot in general, and helped test the reference implementation in
various Scheme systems; to Michael Burschik for his numerous comments;
to Sergei Egorov for helping to narrow down the procedures; to Mike
Sperber for putting up with an _extremely_ overdue draft; to Felix
Winkelmann for continually bugging me about finishing up the SRFI so
that it would be only overdue and not withdrawn; and to everyone else
who gave questions, comments, thoughts, or merely attention to the SRFI.

12 References
*************

R5RS
     _R5RS: The Revised ^{5} Report on Scheme_
     R.  Kelsey, W.  Clinger, J.  Rees (editors).
     Higher-Order and Symbolic Computation, Vol.  11, No.  1, September,
     1998
     and
     ACM SIGPLAN Notices, Vol.  33, No.  9, October, 1998
     Available at: <http://www.schemers.org/Documents/Standards/R5RS/>

R7RS-small
     _R7RS: The Revised ^{7} Report on Scheme_
     A.  Shinn et al.  (editors).
     Available at: <http://r7rs.org>

SRFI>> SRFI
     _SRFI: Scheme Request for Implementation_
     The SRFI website can be found at: <https://srfi.schemers.org/>
     The SRFIs mentioned in this document are described later.

SRFI 1
     _SRFI 1: List Library_
     A SRFI of list processing procedures, written by Olin Shivers.
     Available at: <https://srfi.schemers.org/srfi-1/>

SRFI 13
     _SRFI 13: String Library_
     A SRFI of string processing procedures, written by Olin Shivers.
     Available at: <https://srfi.schemers.org/srfi-13/>

SRFI 23
     _SRFI 23: Error Reporting Mechanism_
     A SRFI that defines a new primitive (‘error’) for reporting that an
     error occurred, written by Stephan Houben.
     Available at: <https://srfi.schemers.org/srfi-23/>

SRFI 43
     _SRFI 43: Vector Library (draft)_
     The direct predecessor of this SRFI, written by Taylor Campbell.
     Available at: <https://srfi.schemers.org/srfi-43/>

13 Copyright
************

Copyright (C) Taylor Campbell (2003).  All rights reserved.

   Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

   The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

   Editor: Arthur A.  Gleckler
<srfi+minus+editors+at+srfi+dot+schemers+dot+org>