2012 lines
61 KiB
HTML
2012 lines
61 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<!-- Non-indentation necessary for the commit check junk. -->
|
|
<title>SRFI 43: Vector Library</title>
|
|
<meta http-equiv="Content-type"
|
|
content="text/html; charset=iso-8859-1">
|
|
<style type="text/css">
|
|
/* <![CDATA[ */
|
|
body {
|
|
padding-right: 5%;
|
|
}
|
|
|
|
h2 {
|
|
padding-left: 6%;
|
|
}
|
|
|
|
/* Ugly hack to make the header work right */
|
|
h1.nonheader {
|
|
padding-left: 8.5%;
|
|
}
|
|
|
|
h1 {
|
|
margin-left: -4.5%;
|
|
}
|
|
|
|
div.header {
|
|
padding-left: 8%;
|
|
}
|
|
|
|
p, dl, code.indented {
|
|
padding-left: 8%;
|
|
}
|
|
|
|
ul.outer, dl.indented {
|
|
padding-left: 13%;
|
|
}
|
|
|
|
ul.indented {
|
|
padding-left: 18%;
|
|
}
|
|
|
|
dt.ref {
|
|
font-weight: bold;
|
|
}
|
|
|
|
dt.ref:before {
|
|
content: "[";
|
|
}
|
|
dt.ref:after {
|
|
content: "]";
|
|
}
|
|
|
|
dt.proc-index {
|
|
padding-left: 0.5%;
|
|
font-size: medium;
|
|
font-weight: bold;
|
|
}
|
|
|
|
dt.type-spec {
|
|
font-family: monospace;
|
|
font-style: italic;
|
|
}
|
|
|
|
dt.proc-spec {
|
|
font-family: monospace;
|
|
}
|
|
|
|
code.example-call {
|
|
padding-left: 3%;
|
|
}
|
|
code.example-value {
|
|
padding-left: 8%;
|
|
}
|
|
code.example-value:before {
|
|
content: "=> "
|
|
}
|
|
/* ]]> */
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="header">
|
|
<!--
|
|
Special SRFI header, formatted oddly due to the commit check script
|
|
for SRFI CVS.
|
|
-->
|
|
<H1>Title</H1>
|
|
Vector library
|
|
|
|
<H1>Author</H1>
|
|
Taylor Campbell
|
|
|
|
<H1>Status</H1>
|
|
This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>.
|
|
You can access the discussion via <A HREF="http://srfi.schemers.org/srfi-43/mail-archive/maillist.html">the archive of the mailing list</A>.
|
|
<UL>
|
|
<LI>Received: 2003/03/26
|
|
<LI>Draft: 2003/04/03-2003/06/01
|
|
<LI>Revised: 2003/07/15
|
|
<LI>Revised: 2003/11/01
|
|
<LI>Revised: 2004/04/10
|
|
<LI>Revised: 2004/04/28
|
|
<LI>Revised: 2004/08/30
|
|
<LI>Final: 2004/10/26
|
|
</UL>
|
|
<!--
|
|
End special header.
|
|
-->
|
|
</div>
|
|
|
|
<h1 class="nonheader">Table of Contents</h1>
|
|
<ul class="outer">
|
|
<li>1. <a href="#Abstract">Abstract</a></li>
|
|
<li>2. <a href="#Rationale">Rationale</a></li>
|
|
<li>3. <a href="#ProcIndex">Procedure Index</a></li>
|
|
<li>
|
|
4. <a href="#Procs">Procedures</a>
|
|
<ul>
|
|
<li>4.1. <a href="#Constructors">Constructors</a></li>
|
|
<li>4.2. <a href="#Predicates">Predicates</a></li>
|
|
<li>4.3. <a href="#Selectors">Selectors</a></li>
|
|
<li>4.4. <a href="#Iteration">Iteration</a></li>
|
|
<li>4.5. <a href="#Searching">Searching</a></li>
|
|
<li>4.6. <a href="#Mutators">Mutators</a></li>
|
|
<li>4.7. <a href="#Conversion">Conversion</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>5. <a href="#RefImpl">Reference Implementation</a></li>
|
|
<li>6. <a href="#Acknowledgements">Acknowledgements</a></li>
|
|
<li>7. <a href="#References">References</a></li>
|
|
<li>8. <a href="#Copyright">Copyright</a></li>
|
|
</ul>
|
|
|
|
<h1 class="nonheader"><a name="Abstract">1. Abstract</a></h1>
|
|
<p>
|
|
This <a href="#SRFI">SRFI</a> proposes a comprehensive and
|
|
complete 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
|
|
<a href="#R5RS">R5RS</a>-compliant. It also provides several
|
|
hooks for implementation-specific optimization as well.
|
|
</p>
|
|
|
|
<p>
|
|
Because this SRFI is more of a library or module specification
|
|
than a request for additions to readers or any other internal
|
|
implementation detail, in an implementation that supports a
|
|
module or structure or package or library or unit (et cetera)
|
|
systems, these procedures should be contained in a module /
|
|
structure / package / library / unit called <tt>vector-lib</tt>.
|
|
</p>
|
|
|
|
<h1 class="nonheader"><a name="Rationale">2. Rationale</a></h1>
|
|
<p>
|
|
<a href="#R5RS">R5RS</a> provides very few list-processing
|
|
procedures, for which reason <a href="#SRFI-1">SRFI 1
|
|
(<tt>list-lib</tt>)</a> exists. However,
|
|
<a href="#R5RS">R5RS</a> provides even fewer vector operations
|
|
— while it provides mapping, appending, et cetera
|
|
operations for lists, it specifies only nine vector manipulation
|
|
operations —:
|
|
</p>
|
|
|
|
<ul class="indented">
|
|
<li><tt><a href="#vector-p">vector?</a></tt></li>
|
|
<li><tt><a href="#make-vector">make-vector</a></tt></li>
|
|
<li><tt><a href="#vector">vector</a></tt></li>
|
|
<li><tt><a href="#vector-length">vector-length</a></tt></li>
|
|
<li><tt><a href="#vector-ref">vector-ref</a></tt></li>
|
|
<li><tt><a href="#vector-set-bang">vector-set!</a></tt></li>
|
|
<li><tt><a href="#vector-to-list">vector->list</a></tt></li>
|
|
<li><tt><a href="#list-to-vector">list->vector</a></tt></li>
|
|
<li><tt><a href="#vector-fill-bang">vector-fill!</a></tt></li>
|
|
</ul>
|
|
|
|
<p>
|
|
Many Scheme implementations provide several vector operations
|
|
beyond the minuscule set that R5RS defines (the typical
|
|
<tt><a href="#vector-append">vector-append</a></tt>,
|
|
<tt><a href="#vector-map">vector-map</a></tt>, et cetera), but
|
|
often these procedures have different names, take arguments in
|
|
different orders, don't take the same number of arguments, or
|
|
have some other flaw that makes them unportable. For this
|
|
reason, this SRFI is proposed.
|
|
</p>
|
|
|
|
<p>
|
|
It should be noted that no vector sorting procedures are provided
|
|
by this SRFI, because there already is a SRFI for such a purpose
|
|
(<a href="#SRFI-32">SRFI 32 (<tt>sort-lib</tt>)</a>), which
|
|
includes routines for sorting not only vectors but also lists.
|
|
</p>
|
|
|
|
<h1 class="nonheader">
|
|
<a name="ProcIndex">3. Procedure Index</a>
|
|
</h1>
|
|
<p>
|
|
Here is an index of the procedures provided by this package.
|
|
Those marked by <b>bold</b> are provided in
|
|
<a href="#R5RS">R5RS</a> and those marked by <b><i>bold
|
|
italic</i></b> are defined by <a href="#R5RS">R5RS</a> but are
|
|
modified from their original definitions.
|
|
</p>
|
|
<dl>
|
|
<dt class="proc-index">
|
|
· <a href="#Constructors">Constructors</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<b><a href="#make-vector">make-vector</a></b>
|
|
<b><a href="#vector">vector</a></b>
|
|
<br>
|
|
<a href="#vector-tabulate">vector-unfold</a>
|
|
<a href="#vector-unfold-right">vector-unfold-right</a>
|
|
<br>
|
|
<a href="#vector-copy">vector-copy</a>
|
|
<a href="#vector-reverse-copy">vector-reverse-copy</a>
|
|
<br>
|
|
<a href="#vector-append">vector-append</a>
|
|
<a href="#vector-concatenate">vector-concatenate</a>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Predicates">Predicates</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<b><a href="#vector-p">vector?</a></b>
|
|
<br>
|
|
<a href="#vector-empty-p">vector-empty?</a>
|
|
<br>
|
|
<a href="#vector-eq">vector=</a>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Selectors">Selectors</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<b><a href="#vector-ref">vector-ref</a></b>
|
|
<br>
|
|
<b><a href="#vector-length">vector-length</a></b>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Iteration">Iteration</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<a href="#vector-fold">vector-fold</a>
|
|
<a href="#vector-fold-right">vector-fold-right</a>
|
|
<br>
|
|
<a href="#vector-map">vector-map</a>
|
|
<a href="#vector-map-bang">vector-map!</a>
|
|
<br>
|
|
<a href="#vector-for-each">vector-for-each</a>
|
|
<br>
|
|
<a href="#vector-count">vector-count</a>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Searching">Searching</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<a href="#vector-index">vector-index</a>
|
|
<a href="#vector-index-right">vector-index-right</a>
|
|
<br>
|
|
<a href="#vector-skip">vector-skip</a>
|
|
<a href="#vector-skip-right">vector-skip-right</a>
|
|
<br>
|
|
<a href="#vector-binary-search">vector-binary-search</a>
|
|
<br>
|
|
<a href="#vector-any">vector-any</a>
|
|
<a href="#vector-every">vector-every</a>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Mutators">Mutators</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<b><a href="#vector-set-bang">vector-set!</a></b>
|
|
<a href="#vector-swap-bang">vector-swap!</a>
|
|
<br>
|
|
<b><i><a href="#vector-fill-bang">vector-fill!</a></i></b>
|
|
<br>
|
|
<a href="#vector-reverse-bang">vector-reverse!</a>
|
|
<br>
|
|
<a href="#vector-copy-bang">vector-copy!</a>
|
|
<a href="#vector-reverse-copy-bang">vector-reverse-copy!</a>
|
|
<br>
|
|
<br>
|
|
</code>
|
|
</dd>
|
|
|
|
<dt class="proc-index">
|
|
· <a href="#Conversion">Conversion</a>
|
|
<br>
|
|
<br>
|
|
</dt>
|
|
<dd>
|
|
<code>
|
|
<b><i><a href="#vector-to-list">vector->list</a></i></b>
|
|
<a href="#reverse-vector-to-list">reverse-vector->list</a>
|
|
<br>
|
|
<b><i><a href="#list-to-vector">list->vector</a></i></b>
|
|
<a href="#reverse-list-to-vector">reverse-list->vector</a>
|
|
</code>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h1 class="nonheader"><a name="Procs">4. Procedures</a></h1>
|
|
<p>
|
|
In this section containing specifications of procedures, the
|
|
following notation is used to specify parameters and return
|
|
values:
|
|
</p>
|
|
<dl class="indented">
|
|
<dt class="type-spec">
|
|
(f arg<sub>1</sub> arg<sub>2</sub> ···)
|
|
-> something</dt>
|
|
<dd>
|
|
Indicates a function <tt><i>f</i></tt> takes the parameters
|
|
<tt><i>arg<sub>1</sub> arg<sub>2</sub>
|
|
···</i></tt> and returns a value of the
|
|
type <tt><i>something</i></tt>. If <tt><i>something</i></tt>
|
|
is <tt>unspecified</tt>, then what <tt><i>f</i></tt> returns is
|
|
implementation-dependant; this SRFI does not specify what it
|
|
returns, and in order to write portable code, the return value
|
|
should be ignored.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">vec</dt>
|
|
<dd>
|
|
The argument in this place must be a vector, i.e. it must
|
|
satisfy the predicate
|
|
<tt><a href="#vector-p">vector?</a></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">i, j, start, size</dt>
|
|
<dd>
|
|
The argument in this place must be a nonnegative integer, i.e.
|
|
it must satisfy the predicates <tt>integer?</tt> and either
|
|
<tt>zero?</tt> or <tt>positive?</tt>. The third case of it
|
|
indicates the index at which traversal begins; the fourth case
|
|
of it indicates the size of a vector.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">end</dt>
|
|
<dd>
|
|
The argument in this place must be a positive integer, i.e. it
|
|
must satisfy the predicates <tt>integer?</tt> and
|
|
<tt>positive?</tt>. This indicates the index directly before
|
|
which traversal will stop — processing will occur until
|
|
the index of the vector is <tt><i>end</i></tt>. It is the
|
|
closed right side of a range.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">f</dt>
|
|
<dd>
|
|
The argument in this place must be a function of one or more
|
|
arguments, returning exactly one value.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">pred?</dt>
|
|
<dd>
|
|
The argument in this place must be a function of one or more
|
|
arguments that returns one value, which is treated as a
|
|
boolean.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">
|
|
x, y, z, seed, knil, fill, key, value
|
|
</dt>
|
|
<dd>
|
|
The argument in this place may be any Scheme value.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">[something]</dt>
|
|
<dd>
|
|
Indicates that <tt><i>something</i></tt> is an optional
|
|
argument; it needn't necessarily be applied.
|
|
<tt><i>Something</i></tt> needn't necessarily be one thing; for
|
|
example, this usage of it is perfectly valid:
|
|
<br>
|
|
<br>
|
|
<code>
|
|
[start [end]]
|
|
</code>
|
|
<br>
|
|
<br>
|
|
and is indeed used quite often.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">something ···</dt>
|
|
<dd>
|
|
Indicates that zero or more <tt><i>something</i></tt>s are
|
|
allowed to be arguments.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">
|
|
something<sub>1</sub> something<sub>2</sub>
|
|
···
|
|
</dt>
|
|
<dd>
|
|
Indicates that at least one <tt><i>something</i></tt> must be
|
|
arguments.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="type-spec">
|
|
something<sub>1</sub> something<sub>2</sub>
|
|
···
|
|
something<sub>n</sub>
|
|
</dt>
|
|
<dd>
|
|
Exactly equivalent to the previous argument notation, but this
|
|
also indicates that <tt><i>n</i></tt> will be used later in the
|
|
procedure description.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>
|
|
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 <tt><a href="#vector-eq">vector=</a></tt>, which
|
|
automatically returns <tt>#f</tt> if the vectors' lengths vary.
|
|
<p>
|
|
|
|
<h2><a name="Constructors">4.1. Constructors</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="make-vector">
|
|
(make-vector <i>size</i> [<i>fill</i>])
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Creates and returns a vector
|
|
of size <tt><i>size</i></tt>, optionally filling it with
|
|
<tt><i>fill</i></tt>. The default value of
|
|
<tt><i>fill</i></tt> is unspecified.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(make-vector 5 3)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(3 3 3 3 3)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector">
|
|
(vector <i>x ···</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Creates and returns a vector
|
|
whose elements are <tt><i>x ···</i></tt>.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector 0 1 2 3 4)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(0 1 2 3 4)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-unfold">
|
|
(vector-unfold <i>f length initial-seed
|
|
···</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
The fundamental vector constructor. Creates a vector whose
|
|
length is <tt><i>length</i></tt> and iterates across each index
|
|
<tt><i>k</i></tt> between <tt>0</tt> and
|
|
<tt><i>length</i></tt>, applying <tt><i>f</i></tt> at each
|
|
iteration to the current index and current seeds, in that
|
|
order, to receive <tt><i>n</i> + 1</tt> values: first, the
|
|
element to put in the <tt><i>k</i></tt>th slot of the new
|
|
vector and <tt><i>n</i></tt> new seeds for the next iteration.
|
|
It is an error for the number of seeds to vary between
|
|
iterations.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-unfold (λ (i x) (values x (- x 1)))
|
|
<br>
|
|
|
|
10 0)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Construct a vector of the sequence of integers in the range
|
|
[0,<tt><i>n</i></tt>).
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-unfold values <tt><i>n</i></tt>)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(0 1 2 ··· <i>n-2</i> <i>n-1</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Copy <tt><i>vector</i></tt>.
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-unfold (λ (i) (vector-ref <i>vector</i> i))
|
|
<br>
|
|
|
|
(vector-length <i>vector</i>))
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-unfold-right">
|
|
(vector-unfold-right <i>f length initial-seed
|
|
···</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-unfold">vector-unfold</a></tt>, but
|
|
it uses <tt><i>f</i></tt> to generate elements from
|
|
right-to-left, rather than left-to-right.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
Construct a vector in reverse of the integers in the range
|
|
[0,<tt><i>n</i></tt>).
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-unfold-right (λ (i x) (values x (+ x 1))) <i>n</i> 0)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(<i>n-1</i> <i>n-2</i> ··· 2 1 0)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Reverse <tt><i>vector</i></tt>.
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-unfold-right (λ (i x)
|
|
(values (vector-ref <i>vector</i> x)
|
|
(+ x 1)))
|
|
<br>
|
|
|
|
(vector-length <i>vector</i>)
|
|
<br>
|
|
|
|
0)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<!-- VECTOR-TABULATE has been flushed in favour of VECTOR-UNFOLD.
|
|
<dt class="proc-spec">
|
|
<a name="vector-tabulate">
|
|
(vector-tabulate <i>f size</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Creates a new vector whose size is <tt><i>size</i></tt> and
|
|
fills it by applying <tt><i>f</i></tt> to each index in the
|
|
vector, in an unspecified order.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-tabulate - 5)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(0 -1 -2 -3 -4)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-tabulate (λ (x) (* x x)) 5)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(0 1 4 9 16)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
-->
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-copy">
|
|
(vector-copy <i>vec</i>
|
|
[<i>start</i> [<i>end</i> [<i>fill</i>]]])
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Allocates a new vector whose length is <tt><i>end</i> -
|
|
<i>start</i></tt> and fills it with elements from
|
|
<tt><i>vec</i></tt>, taking elements from <tt><i>vec</i></tt>
|
|
starting at index <tt><i>start</i></tt> and stopping at index
|
|
<tt><i>end</i></tt>. <tt><i>start</i></tt> defaults to
|
|
<tt>0</tt> and <tt><i>end</i></tt> defaults to the value of
|
|
<tt>(<a href="#vector-length">vector-length</a>
|
|
<i>vec</i>)</tt>. If <tt><i>end</i></tt> extends beyond the
|
|
length of <tt><i>vec</i></tt>, the slots in the new vector that
|
|
obviously cannot be filled by elements from <tt><i>vec</i></tt>
|
|
are filled with <tt><i>fill</i></tt>, whose default value is
|
|
unspecified.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-copy '#(a b c d e f g h i))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(a b c d e f g h i)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-copy '#(a b c d e f g h i) 6)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(g h i)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-copy '#(a b c d e f g h i) 3 6)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(d e f)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-copy '#(a b c d e f g h i) 6 12 'x)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(g h i x x x)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-reverse-copy">
|
|
(vector-reverse-copy <i>vec</i>
|
|
[<i>start</i> [<i>end</i>]])
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-copy">vector-copy</a></tt>, but it
|
|
copies the elements in the reverse order from
|
|
<tt><i>vec</i></tt>.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-reverse-copy '#(5 4 3 2 1 0) 1 5)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(1 2 3 4)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-append">
|
|
(vector-append <i>vec ···</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Returns a newly allocated vector that contains all elements in
|
|
order from the subsequent locations in <tt><i>vec
|
|
···</i></tt>.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-append '#(x) '#(y))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(x y)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-append '#(a) '#(b c d))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(a b c d)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-append '#(a #(b)) '#(#(c)))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(a #(b) #(c))
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-concatenate">
|
|
(vector-concatenate <i>list-of-vectors</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Appends each vector in <tt><i>list-of-vectors</i></tt>. This
|
|
is equivalent to:
|
|
<br>
|
|
<br>
|
|
<code class="indented">
|
|
(apply <a href="#vector-append">vector-append</a>
|
|
<i>list-of-vectors</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
However, it may be implemented better.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-concatenate '(#(a b) #(c d)))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(a b c d)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Predicates">4.2. Predicates</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-p">
|
|
(vector? <i>x</i>)
|
|
-> boolean
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Disjoint type predicate for
|
|
vectors: this returns <tt>#t</tt> if <tt><i>x</i></tt> is a
|
|
vector, and <tt>#f</tt> if otherwise.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector? '#(a b c))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector? '(a b c))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector? #t)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector? '#())
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector? '())
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-empty-p">
|
|
(vector-empty? <i>vec</i>)
|
|
-> boolean
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Returns <tt>#t</tt> if <tt><i>vec</i></tt> is empty, i.e. its
|
|
length is <tt>0</tt>, and <tt>#f</tt> if not.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-empty? '#(a))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-empty? '#(()))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-empty? '#(#()))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-empty? '#())
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-eq">
|
|
(vector= <i>elt=? vec ···</i>)
|
|
-> boolean
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Vector structure comparator, generalized across user-specified
|
|
element comparators. Vectors <tt><i>a</i></tt> and
|
|
<tt><i>b</i></tt> are considered equal by <tt>vector=</tt> iff
|
|
their lengths are the same, and for each respective elements
|
|
<tt><i>E</i><sub>a</sub></tt> and
|
|
<tt><i>E</i><sub>b</sub></tt>, <tt>(<i>elt=? E</i><sub>a</sub>
|
|
<i>E</i><sub>b</sub>)</tt> returns a true value.
|
|
<tt><i>Elt=?</i></tt> is always applied to two arguments.
|
|
Element comparison must be consistent with <tt>eq</tt>; that
|
|
is, if <tt>(eq? <i>E</i><sub>a</sub> <i>E</i><sub>b</sub>)</tt>
|
|
results in a true value, then <tt>(<i>elt=? E</i><sub>a</sub>
|
|
<i>E</i><sub>b</sub>)</tt> must also result in a true value.
|
|
This may be exploited to avoid unnecessary element comparisons.
|
|
(The reference implementation does, but it does not consider
|
|
the situation where <tt><i>elt=?</i></tt> is in fact itself
|
|
<tt>eq?</tt> to avoid yet more unnecessary comparisons.)
|
|
<br>
|
|
<br>
|
|
If there are only zero or one vector arguments, <tt>#t</tt> 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.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= eq? '#(a b c d) '#(a b c d))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= eq? '#(a b c d) '#(a b d c))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= = '#(1 2 3 4 5) '#(1 2 3 4))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= = '#(1 2 3 4) '#(1 2 3 4))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
The two trivial cases.
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= eq?)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= eq? '#(a))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
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 <tt>eq?</tt>.
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= eq? (vector (vector 'a)) (vector (vector 'a)))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector= equal? (vector (vector 'a)) (vector (vector 'a)))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#t
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Selectors">4.3. Selectors</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-ref">
|
|
(vector-ref <i>vec i</i>)
|
|
-> value
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Vector element dereferencing:
|
|
returns the value that the location in <tt><i>vec</i></tt> at
|
|
<tt><i>i</i></tt> is mapped to in the store. Indexing is based
|
|
on zero. <tt><i>I</i></tt> must be within the range [0,
|
|
<tt>(<a href="#vector-length">vector-length</a>
|
|
<i>vec</i>)</tt>).
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-ref '#(a b c d) 2)
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
c
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-length">
|
|
(vector-length <i>vec</i>)
|
|
-> exact nonnegative integer
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Returns the length of <tt><i>vec</i></tt>, the number of
|
|
locations reachable from <tt><i>vec</i></tt>. (The careful
|
|
word 'reachable' is used to allow for 'vector slices,' whereby
|
|
<tt><i>vec</i></tt> refers to a larger vector that contains
|
|
more locations that are unreachable from <tt><i>vec</i></tt>.
|
|
This SRFI does not define vector slices, but later SRFIs may.)
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-length '#(a b c))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
3
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Iteration">4.4. Iteration</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-fold">
|
|
(vector-fold <i>kons knil vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> value
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
The fundamental vector iterator. <tt><i>Kons</i></tt> is
|
|
iterated over each index in all of the vectors, stopping at the
|
|
end of the shortest; <tt><i>kons</i></tt> is applied as
|
|
<tt>
|
|
(<i>kons</i> <i>i</i> <i>state</i>
|
|
(<a href="#vector-ref">vector-ref</a>
|
|
<i>vec<sub>1</sub></i> <i>i</i>)
|
|
(<a href="#vector-ref">vector-ref</a>
|
|
<i>vec<sub>2</sub></i> <i>i</i>)
|
|
···)
|
|
</tt>
|
|
where <tt><i>state</i></tt> is the current state value —
|
|
the current state value begins with <tt><i>knil</i></tt>, and
|
|
becomes whatever <tt><i>kons</i></tt> returned at the
|
|
respective iteration —, and <tt><i>i</i></tt> is the
|
|
current index.
|
|
<br>
|
|
<br>
|
|
The iteration is strictly left-to-right.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
Find the longest string's length in
|
|
<tt><i>vector-of-strings</i></tt>.
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-fold (λ (index len str)
|
|
(max (string-length str) len))
|
|
<br>
|
|
|
|
0 <i>vector-of-strings</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Produce a list of the reversed elements of
|
|
<tt><i>vec</i></tt>.
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-fold (λ (index tail elt) (cons elt tail))
|
|
<br>
|
|
|
|
'() <i>vec</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Count the number of even numbers in <tt><i>vec</i></tt>.
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-fold (λ (index counter n)
|
|
<br>
|
|
|
|
(if (even? n) (+ counter 1) counter))
|
|
<br>
|
|
|
|
0 <i>vec</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-fold-right">
|
|
(vector-fold-right <i>kons knil
|
|
vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> value
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Similar to <tt><a href="#vector-fold">vector-fold</a></tt>, but
|
|
it iterates right to left instead of left to right.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
Convert a vector to a list.
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-fold-right (λ (index tail elt)
|
|
(cons elt tail))
|
|
<br>
|
|
|
|
'() '#(a b c d))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
(a b c d)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-map">
|
|
(vector-map <i>f vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Constructs a new vector of the shortest size of the vector
|
|
arguments. Each element at index <tt><i>i</i></tt> of the new
|
|
vector is mapped from the old vectors by
|
|
<tt>(<i>f</i> <i>i</i>
|
|
(<a href="#vector-ref">vector-ref</a>
|
|
<i>vec<sub>1</sub></i>
|
|
<i>i</i>)
|
|
(<a href="#vector-ref">vector-ref</a>
|
|
<i>vec<sub>2</sub></i>
|
|
<i>i</i>)
|
|
···)</tt>.
|
|
The dynamic order of application of <tt><i>f</i></tt> is
|
|
unspecified.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-map (λ (i x) (* x x))
|
|
<br>
|
|
|
|
(<a href="#vector-unfold">vector-unfold</a>
|
|
(λ (i x) (values x (+ x 1)))
|
|
4 1))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(1 4 9 16)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-map (λ (i x y) (* x y))<br>
|
|
|
|
(<a href="#vector-unfold">vector-unfold</a>
|
|
(λ (i x) (values x (+ x 1)))
|
|
5 1)<br>
|
|
|
|
(<a href="#vector-unfold">vector-unfold</a>
|
|
(λ (i x) (values x (- x 1)))
|
|
5 5))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(5 8 9 8 5)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(let ((count 0))
|
|
</code>
|
|
<br>
|
|
<code class="example-call">
|
|
|
|
(vector-map (λ (ignored-index ignored-elt)
|
|
</code>
|
|
<br>
|
|
<code class="example-call">
|
|
|
|
|
|
(set! count (+ count 1))
|
|
</code>
|
|
<br>
|
|
<code class="example-call">
|
|
|
|
|
|
count)
|
|
</code>
|
|
<br>
|
|
<code class="example-call">
|
|
|
|
|
|
'#(a b)))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(1 2) <i>OR</i> #(2 1)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-map (λ (i elt) (+ i elt)) '#(1 2 3 4))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#(1 3 5 7)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-map-bang">
|
|
(vector-map! <i>f vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Similar to <tt><a href="#vector-map">vector-map</a></tt>, but
|
|
rather than mapping the new elements into a new vector, the new
|
|
mapped elements are destructively inserted into
|
|
<tt><i>vec<sub>1</sub></i></tt>. Again, the dynamic order of
|
|
application of <tt><i>f</i></tt> unspecified, so it is
|
|
dangerous for <tt><i>f</i></tt> to apply either
|
|
<tt><a href="#vector-ref">vector-ref</a></tt> or
|
|
<tt><a href="#vector-set-bang">vector-set!</a></tt> to
|
|
<tt><i>vec<sub>1</sub></i></tt> in <tt><i>f</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-for-each">
|
|
(vector-for-each <i>f vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Simple vector iterator: applies <tt><i>f</i></tt> to each index
|
|
in the range [0, <tt><i>length</i></tt>), where
|
|
<tt><i>length</i></tt> is the length of the smallest vector
|
|
argument passed, and the respective list of parallel elements
|
|
from <tt><i>vec<sub>1</sub> vec<sub>2</sub></i>
|
|
···</tt> at that index. In contrast with
|
|
<tt><a href="#vector-map">vector-map</a></tt>, <tt><i>f</i></tt>
|
|
is reliably applied to each subsequent elements, starting at
|
|
index 0, in the vectors.
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-for-each (λ (i x) (display x) (newline))
|
|
</code>
|
|
<br>
|
|
<code class="example-call">
|
|
|
|
|
|
'#("foo" "bar" "baz" "quux" "zot"))
|
|
</code>
|
|
<br>
|
|
Displays:
|
|
<br>
|
|
<pre>
|
|
foo
|
|
bar
|
|
baz
|
|
quux
|
|
zot</pre>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-count">
|
|
(vector-count <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> exact nonnegative integer
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Counts the number of parallel elements in the vectors that
|
|
satisfy <tt><i>pred?</i></tt>, which is applied, for each index
|
|
<tt><i>i</i></tt> in the range [0, <tt><i>length</i></tt>)
|
|
— where <tt><i>length</i></tt> is the length of the
|
|
smallest vector argument —, to <tt><i>i</i></tt> and each
|
|
parallel element in the vectors at that index, in order.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-count (λ (i elt) (even? elt))
|
|
'#(3 1 4 1 5 9 2 5 6))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
3
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-count (λ (i x y) (< x y))
|
|
'#(1 3 6 9) '#(2 4 6 8 10 12))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
2
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Searching">4.5. Searching</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-index">
|
|
(vector-index <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> exact nonnegative integer or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Finds & returns the index of the first elements in
|
|
<tt><i>vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i></tt> that satisfy
|
|
<tt><i>pred?</i></tt>. If no matching element is found by the
|
|
end of the shortest vector, <tt>#f</tt> is returned.
|
|
<br>
|
|
<br>
|
|
Examples:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-index even? '#(3 1 4 1 5 9))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
2
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
1
|
|
</code>
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
#f
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-index-right">
|
|
(vector-index-right <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> exact nonnegative integer or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-index">vector-index</a></tt>, but it
|
|
searches right-to-left, rather than left-to-right, and all of
|
|
the vectors <i>must</i> have the same length.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-skip">
|
|
(vector-skip <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> exact nonnegative integer or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Finds & returns the index of the first elements in
|
|
<tt><i>vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i></tt> that do <i>not</i> satisfy
|
|
<tt><i>pred?</i></tt>. If all the values in the vectors
|
|
satisfy <tt><i>pred?</i></tt> until the end of the shortest
|
|
vector, this returns <tt>#f</tt>. This is equivalent to:
|
|
<br>
|
|
<br>
|
|
<code class="indented">
|
|
(<a href="#vector-index">vector-index</a>
|
|
(λ (x<sub><i>1</i></sub> x<sub><i>2</i></sub>
|
|
<i>···</i>)
|
|
(not (<i>pred?</i> x<sub><i>1</i></sub>
|
|
x<sub><i>1</i></sub>
|
|
<i>···</i>)))
|
|
<br>
|
|
|
|
<i>vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
Example:
|
|
<br>
|
|
<br>
|
|
<code class="example-call">
|
|
(vector-skip number? '#(1 2 a b 3 4 c d))
|
|
</code>
|
|
<br>
|
|
<code class="example-value">
|
|
2
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-skip-right">
|
|
(vector-skip-right <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> exact nonnegative integer or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-skip">vector-skip</a></tt>, but it
|
|
searches for a non-matching element right-to-left, rather than
|
|
left-to-right, and all of the vectors <i>must</i> have the same
|
|
length. This is equivalent to:
|
|
<br>
|
|
<br>
|
|
<code class="indented">
|
|
(<a href="#vector-index">vector-index-right</a>
|
|
(λ (x<sub><i>1</i></sub> x<sub><i>2</i></sub>
|
|
<i>···</i>)
|
|
(not (<i>pred?</i> x<sub><i>1</i></sub>
|
|
x<sub><i>1</i></sub>
|
|
<i>···</i>)))
|
|
<br>
|
|
|
|
|
|
<i>vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-binary-search">
|
|
(vector-binary-search <i>vec value cmp</i>)
|
|
-> exact nonnegative integer or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Similar to <tt><a href="#vector-index">vector-index</a></tt>
|
|
and
|
|
<tt><a href="#vector-index-right">vector-index-right</a></tt>,
|
|
but instead of searching left to right or right to left, this
|
|
performs a binary search. <tt><i>cmp</i></tt> 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 <tt><i>cmp</i></tt> might
|
|
be:
|
|
<br>
|
|
<br>
|
|
<code class="indented">
|
|
(λ (<i>char<sub>1</sub></i> <i>char<sub>2</sub></i>)
|
|
</code>
|
|
<br>
|
|
<code class="indented">
|
|
(cond ((char<? <i>char<sub>1</sub>
|
|
char<sub>2</sub></i>)
|
|
-1)
|
|
</code>
|
|
<br>
|
|
<code class="indented">
|
|
|
|
((char=? <i>char<sub>1</sub>
|
|
char<sub>2</sub></i>)
|
|
0)
|
|
</code>
|
|
<br>
|
|
<code class="indented">
|
|
|
|
(else 1)))
|
|
</code>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-any">
|
|
(vector-any <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> value or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Finds the first set of elements in parallel from
|
|
<tt><i>vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i></tt> for which
|
|
<tt><i>pred?</i></tt> returns a true value. If such a parallel
|
|
set of elements exists, <tt>vector-any</tt> returns the value
|
|
that <tt><i>pred?</i></tt> returned for that set of elements.
|
|
The iteration is strictly left-to-right.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-every">
|
|
(vector-every <i>pred? vec<sub>1</sub> vec<sub>2</sub>
|
|
···</i>)
|
|
-> value or #f
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
If, for every index <tt><i>i</i></tt> between 0 and the length
|
|
of the shortest vector argument, the set of elements
|
|
<tt>(<a href="#vector-ref">vector-ref</a> <i>vec<sub>1</sub></i>
|
|
<i>i</i>)
|
|
(<a href="#vector-ref">vector-ref</a> <i>vec<sub>2</sub></i>
|
|
<i>i</i>)
|
|
···</tt>
|
|
satisfies <tt><i>pred?</i></tt>, <tt>vector-every</tt> returns
|
|
the value that <tt><i>pred?</i></tt> returned for the last
|
|
set of elements, at the last index of the shortest vector. The
|
|
iteration is strictly left-to-right.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Mutators">4.6. Mutators</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-set-bang">
|
|
(vector-set! <i>vec i value</i>)
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>] Assigns the contents of the location at <tt><i>i</i></tt> in
|
|
<tt><i>vec</i></tt> to <tt><i>value</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-swap-bang">
|
|
(vector-swap! <i>vec i j</i>)
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Swaps or exchanges the values of the locations in
|
|
<tt><i>vec</i></tt> at <tt><i>i</i></tt> &
|
|
<tt><i>j</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-fill-bang">
|
|
(vector-fill! <i>vec fill</i> [<i>start</i> [<i>end</i>]])
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>+] Assigns the value of every location in <tt><i>vec</i></tt>
|
|
between <tt><i>start</i></tt>, which defaults to <tt>0</tt> and
|
|
<tt><i>end</i></tt>, which defaults to the length of
|
|
<tt><i>vec</i></tt>, to <tt><i>fill</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-reverse-bang">
|
|
(vector-reverse! <i>vec</i> [<i>start</i> [<i>end</i>]])
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Destructively reverses the contents of the sequence of
|
|
locations in <tt><i>vec</i></tt> between <tt><i>start</i></tt>
|
|
and <tt><i>end</i></tt>. <tt><i>Start</i></tt> defaults to
|
|
<tt>0</tt> and <tt><i>end</i></tt> defaults to the length of
|
|
<tt><i>vec</i></tt>. Note that this does not deeply reverse.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-copy-bang">
|
|
(vector-copy! <i>target tstart source</i>
|
|
[<i>sstart</i> [<i>send</i>]])
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Copies a block of elements from <tt><i>source</i></tt> to
|
|
<tt><i>target</i></tt>, both of which must be vectors, starting
|
|
in <tt><i>target</i></tt> at <tt><i>tstart</i></tt> and
|
|
starting in <tt><i>source</i></tt> at <tt><i>sstart</i></tt>,
|
|
ending when <tt><i>send</i> - <i>sstart</i></tt> elements have
|
|
been copied. It is an error for <tt><i>target</i></tt> to have
|
|
a length less than <tt><i>tstart</i> + (<i>send</i> -
|
|
<i>sstart</i>)</tt>. <tt><i>Sstart</i></tt> defaults to
|
|
<tt>0</tt> and <tt><i>send</i></tt> defaults to the length of
|
|
<tt><i>source</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="vector-reverse-copy-bang">
|
|
(vector-reverse-copy! <i>target tstart source</i>
|
|
[<i>sstart</i> [<i>send</i>]])
|
|
-> unspecified
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-copy-bang">vector-copy!</a></tt>, but
|
|
this copies the elements in the reverse order. It is an error
|
|
if <tt><i>target</i></tt> and <tt><i>source</i></tt> are
|
|
identical vectors and the target & source ranges overlap;
|
|
however, if <tt><i>tstart</i> = <i>sstart</i></tt>,
|
|
<tt>vector-reverse-copy!</tt> behaves as
|
|
<tt>
|
|
(<a href="#vector-reverse-bang">vector-reverse!</a>
|
|
<i>target</i>
|
|
<i>tstart</i>
|
|
<i>send</i>)
|
|
</tt>
|
|
would.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h2><a name="Conversion">4.7. Conversion</a></h2>
|
|
<dl>
|
|
<dt class="proc-spec">
|
|
<a name="vector-to-list">
|
|
(vector->list <i>vec</i> [<i>start</i> [<i>end</i>]])
|
|
-> proper-list
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>+] Creates a list containing the elements in <tt><i>vec</i></tt>
|
|
between <tt><i>start</i></tt>, which defaults to <tt>0</tt>,
|
|
and <tt><i>end</i></tt>, which defaults to the length of
|
|
<tt><i>vec</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="reverse-vector-to-list">
|
|
(reverse-vector->list <i>vec</i>
|
|
[<i>start</i> [<i>end</i>]])
|
|
-> proper-list
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#vector-to-list">vector->list</a></tt>,
|
|
but the resulting list contains the elements in reverse between
|
|
the specified range.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="list-to-vector">
|
|
(list->vector <i>proper-list</i>) -> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
[<a href="#R5RS"><i>R5RS</i></a>+] Creates a vector of elements from <tt><i>proper-list</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="proc-spec">
|
|
<a name="reverse-list-to-vector">
|
|
(reverse-list->vector <i>proper-list</i>) -> vector
|
|
</a>
|
|
</dt>
|
|
<dd>
|
|
Like <tt><a href="#list-to-vector">list->vector</a></tt>,
|
|
but the resulting list contains the elements in reverse of
|
|
<tt><i>proper-list</i></tt>.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h1 class="nonheader">
|
|
<a name="RefImpl">5. Reference Implementation</a>
|
|
</h1>
|
|
<p>
|
|
With this SRFI comes a complete reference implementation. It is
|
|
licensed under a very open copyright with which no implementors
|
|
should have any legal issues.
|
|
<br>
|
|
<br>
|
|
The reference implementation has only one non-R5RS dependency:
|
|
<a href="#SRFI-23">SRFI 23</a>'s <tt>error</tt> procedure.
|
|
<br>
|
|
<br>
|
|
This reference implementation of all the procedures described in
|
|
this SRFI can be found <a href="#vector-lib.scm">here</a>.
|
|
</p>
|
|
|
|
<h1 class="nonheader">
|
|
<a name="Acknowledgements">6. Acknowledgements</a>
|
|
</h1>
|
|
<p>
|
|
Thanks to Olin Shivers for his wonderfully complete
|
|
<a href="#SRFI-1">list</a> and <a href="#SRFI-13">string</a>
|
|
packages; to all the members of the
|
|
<a href="http://scheme-irc.webhop.org/"><tt>#scheme</tt> IRC
|
|
channel</a> on <a href="http://www.freenode.net/">Freenode</a>
|
|
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 <i>extremely</i> 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.
|
|
</p>
|
|
|
|
<h1 class="nonheader"><a name="References">7. References</a></h1>
|
|
<dl>
|
|
<dt class="ref"><a name="R5RS">R5RS</a></dt>
|
|
<dd>
|
|
<i>R5RS: The Revised<sup>5</sup> Report on Scheme</i>
|
|
<br>
|
|
R. Kelsey, W. Clinger, J. Rees (editors).
|
|
<br>
|
|
Higher-Order and Symbolic Computation, Vol. 11, No. 1,
|
|
September, 1998
|
|
<br>
|
|
and
|
|
<br>
|
|
ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998
|
|
<br>
|
|
Available at:
|
|
<a href="http://www.schemers.org/Documents/Standards/R5RS/">
|
|
http://www.schemers.org/Documents/Standards/R5RS/
|
|
</a>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="ref"><a name="SRFI">SRFI</a></dt>
|
|
<dd>
|
|
<i>SRFI: Scheme Request for Implementation</i>
|
|
<br>
|
|
The SRFI website can be found at:
|
|
<a href="http://srfi.schemers.org/">
|
|
http://srfi.schemers.org/
|
|
</a>
|
|
<br>
|
|
The SRFIs mentioned in this document are described later.
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="ref"><a name="SRFI-1">SRFI 1</a></dt>
|
|
<dd>
|
|
<i>SRFI 1: List Library</i>
|
|
<br>
|
|
A SRFI of list processing procedures, written by Olin Shivers.
|
|
<br>
|
|
Available at:
|
|
<a href="http://srfi.schemers.org/srfi-1/">
|
|
http://srfi.schemers.org/srfi-1/
|
|
</a>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="ref"><a name="SRFI-13">SRFI 13</a></dt>
|
|
<dd>
|
|
<i>SRFI 13: String Library</i>
|
|
<br>
|
|
A SRFI of string processing procedures, written by Olin
|
|
Shivers.
|
|
<br>
|
|
Available at:
|
|
<a href="http://srfi.schemers.org/srfi-13/">
|
|
http://srfi.schemers.org/srfi-13/
|
|
</a>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="ref"><a name="SRFI-23">SRFI 23</a></dt>
|
|
<dd>
|
|
<i>SRFI 23: Error Reporting Mechanism</i>
|
|
<br>
|
|
A SRFI that defines a new primitive (<tt>error</tt>) for
|
|
reporting that an error occurred, written by Stephan Houben.
|
|
<br>
|
|
Available at:
|
|
<a href="http://srfi.schemers.org/srfi-23/">
|
|
http://srfi.schemers.org/srfi-23/
|
|
</a>
|
|
<br>
|
|
<br>
|
|
</dd>
|
|
|
|
<dt class="ref"><a name="SRFI-32">SRFI 32</a></dt>
|
|
<dd>
|
|
<i>SRFI 32: Sort Libraries (draft)</i>
|
|
<br>
|
|
A SRFI of list and vector sorting routines, written by Olin
|
|
Shivers.
|
|
<br>
|
|
Available at:
|
|
<a href="http://srfi.schemers.org/srfi-32/">
|
|
http://srfi.schemers.org/srfi-32/
|
|
</a>
|
|
</dd>
|
|
</dl>
|
|
|
|
<h1 class="nonheader"><a name="Copyright">8. Copyright</a></h1>
|
|
<p>
|
|
Copyright (C) Taylor Campbell (2003). All rights reserved.
|
|
</p>
|
|
<p>
|
|
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:
|
|
</p>
|
|
<p>
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<hr>
|
|
<address>Editor: <a href="mailto:srfi-editors@srfi.schemers.org">Mike Sperber</a></address>
|
|
</body>
|
|
</html>
|