This SRFI is currently in *draft* status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to `srfi-160@nospamsrfi.schemers.org`

. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.

- Received: 2018/5/20
- 60-day deadline: 2018/7/20
- Draft #1 published: 2018/8/21
- Draft #2 published: 2018/9/2
- Draft #3 published: 2018/9/8
- Draft #4 published: 2018/10/10
- Draft #5 published: 2018/10/30
- Draft #6 published: 2018/12/6
- Draft #7 published: 2018/12/22
- Draft #8 published: 2019/1/13
- Draft #9 published: 2019/3/11
- Draft #10 published: 2019/5/21
- Draft #11 published: 2019/7/31

`read`

and `write`

procedures and by the program
parser so that programs can contain references to literal homogeneous
vectors.
- None at present.

`c64vector`

and `c128vector`

types, and
by providing analogues for almost all of the heterogeneous vector procedures
of
SRFI 133. There are some additional procedures, most of which are
closely analogous to the string procedures of
SRFI 152.
Note that there are no conversions between homogeneous vectors and strings in this SRFI. In addition, there is no support for u1vectors (bitvectors) provided, not because they are not useful, but because they are different enough in both specification and implementation to be put into a future SRFI of their own.

There are eight datatypes of exact integer homogeneous vectors (which will be called integer vectors):

`s8vector`

: signed exact integer in the range -2`u8vector`

: unsigned exact integer in the range 0 to 2`s16vector`

: signed exact integer in the range -2`u16vector`

: unsigned exact integer in the range 0 to 2`s32vector`

: signed exact integer in the range -2`u32vector`

: unsigned exact integer in the range 0 to 2`s64vector`

: signed exact integer in the range -2`u64vector`

: unsigned exact integer in the range 0 to 2All are part of SRFI 4.

There are two datatypes of inexact real homogeneous vectors (which will be called float vectors):`f32vector`

: inexact real, typically 32 bits`f64vector`

: inexact real, typically 64 bitsThese are also part of SRFI 4.

The only required difference between the two float vector types is that`f64vector`

s preserve at least as much precision and range as
`f32vector`

s (see the implementation section for details).
And there are two datatypes of inexact complex homogeneous vectors (which will be called complex vectors):

`c64vector`

: inexact complex, typically 64 bits`c128vector`

: inexact complex, typically 128 bits
These are *not* part of SRFI 4.

`c128vector`

s preserve at least as much precision and range as
`c64vector`

s (see the implementation section for details).
A Scheme system that conforms to this SRFI does not have to support
all of these homogeneous vector datatypes. However, a Scheme system
must support float vectors if it
supports Scheme inexact reals (of any precision). A Scheme system
must support complex vectors if it supports Scheme inexact complex numbers
(of any precision). Finally, a Scheme system
must support a particular integer vector datatype if the system's
exact integer datatype contains all the values that can be stored in
such an integer vector. Thus a Scheme system with bignum support must
implement all the integer vector datatypes, but a Scheme system might
only support `s8vector`

s, `u8vector`

s,
`s16vector`

s and `u16vector`

s if it only
supports integers in the range -2`make-@vector`

is really shorthand for the descriptions of the twelve
procedures `make-s8vector`

, `make-u8vector`

, ...
`make-c128vector`

, all of which are exactly the same except that
they construct different homogeneous vector types. Furthermore, except as
otherwise noted, the semantics of each procedure are those of the corresponding
SRFI 133 procedure, except that it is an error to attempt
to insert an invalid value into a homogeneous vector.
Consequently, only a brief description of each procedure is given, and
SRFI 133 (or in some cases SRFI 152) should be consulted for the details.
It is worth mentioning, however, that all the procedures that return one or
more vectors (homogeneous or heterogeneous) invariably return newly allocated
vectors specifically.
In the section containing specifications of procedures, the following notation is used to specify parameters and return values:

*(f arg*_{1}arg_{2}...) -> something-
A procedure

that takes the parameters*f*

and returns a value of the type*arg*_{1}arg_{2}...

. If two values are returned, two types are specified. If*something*

is*something*`unspecified`

, then

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.*f*

*vec*-
Must be a heterogeneous vector, i.e. it must
satisfy the predicate
`vector?`

.

*@vec, @to, @from*-
Must be a homogeneous vector, i.e. it must
satisfy the predicate
`@vector?`

. In`@vector-copy!`

and`reverse-@vector-copy!`

,*@to*is the destination and*@from*is the source.

*i, j, start, at*-
Must be an exact nonnegative integer less than the length of the @vector.
In
`@vector-copy!`

and`reverse-@vector-copy!`

,*at*refers to the destination and*start*to the source.

*end*-
Must be an exact nonnegative integer not less than
*start*. This indicates the index directly before which traversal will stop — processing will occur until the index of the vector is one less than

. It is the open right side of a range.*end*

*f*-
Must be a procedure taking one or more
arguments, which returns (except as noted otherwise) exactly one value.

*pred?*-
Must be a procedure taking one or more
arguments that returns one value, which is treated as a
boolean.

*=*-
Must be an equivalence procedure.

*obj, seed, knil*-
Any Scheme object.

*fill, value*-
Any number that is valid with respect to the
*@vec*.

*[something]*-
An optional argument; it needn't necessarily be applied.

needn't necessarily be one thing; for example, this usage of it is perfectly valid:*Something*

`[start [end]]`

and is indeed used quite often.

*something ...*-
Zero or more

s are allowed to be arguments.*something*

*something*_{1}something_{2}...-
At least one

must be arguments.*something*

The procedures shared with SRFI 4 are marked with [SRFI 4]. The procedures with the same semantics as SRFI 133 are marked with [SRFI 133] unless they are already marked with [SRFI 4]. The procedures analogous to SRFI 152 string procedures are marked with [SRFI 152].

`(make-@vector `

[SRFI 4]*size* [*fill*]) -> @vector

Returns a @vector whose length is *size*. If *fill* is provided,
all the elements of the @vector are initialized to it.

`(@vector `

[SRFI 4]*value ...*) -> @vector

Returns a @vector initialized with *values*.

`(@vector-unfold `

[SRFI 133]*f length seed*) -> @vector

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 state, in that order, to receive two values:
the element to put in the k*th* slot of the new vector and a new state
for the next iteration.
On the first call to *f*, the state's value is *seed*.

`(@vector-unfold-right `

[SRFI 133]*f length seed*) -> @vector

The same as `@vector-unfold`

, but initializes the @vector from right to left.

`(@vector-copy `

[SRFI 133]*@vec* [*start* [*end*]]) -> @vector

Makes a copy of the portion of *@vec* from *start* to *end* and returns it.

`(@vector-reverse-copy `

[SRFI 133]*@vec* [*start* [*end*]]) -> @vector

The same as `@vector-copy`

, but in reverse order.

`(@vector-append `

[SRFI 133]*@vec ...*) -> @vector

Returns a @vector containing all the elements of the *@vecs* in order.

` (@vector-concatenate `

[SRFI 133]*list-of-@vectors*) -> @vector

The same as `@vector-append`

, but takes a list of @vectors rather than
multiple arguments.

`(@vector-append-subvectors [`

[SRFI 133]*@vec start end] ...*) -> @vector

Concatenates the result of applying `@vector-copy`

to each triplet of
*@vec, start, end* arguments, but may be implemented more efficiently.

`(@? `

*obj*) -> boolean

Returns `#t`

if *obj* is a valid element of an
@vector, and `#f`

otherwise.

`(@vector? `

[SRFI 4]*obj*) -> boolean

Returns `#t`

if *obj* is a @vector, and `#f`

otherwise.

`(@vector-empty? `

[SRFI 133]*@vec*) -> boolean

`#t`

if `#f`

otherwise.
`(@vector= `

[SRFI 133]*@vec ...*) -> boolean

Compares the *@vecs* for elementwise equality, using
`=`

to do the comparisons. Returns `#f`

unless all @vectors are the same length.

`(@vector-ref `

[SRFI 4]*@vec i*) -> value

Returns the *i*th element of *@vec*.

`(@vector-length `

[SRFI 4]*@vec*) -> exact nonnegative integer

Returns the length of *@vec*

`(@vector-take `

] [SRFI 152]*@vec n*) -> @vector

`(@vector-take-right `

[SRFI 152]*@vec n*) -> @vector

Returns a @vector containing the first/last *n*
elements of *@vec*.

`(@vector-drop `

[SRFI 152]*@vec n*) -> @vector

`(@vector-drop-right `

[SRFI 152]*@vec n*) -> @vector

Returns a @vector containing all except the first/last *n*
elements of *@vec*.

`(@vector-segment `

[SRFI 152]*@vec n*) -> list

Returns a list of @vectors, each of which contains *n*
consecutive elements of *@vec*.
The last @vector may be shorter than *n*.

`(@vector-fold `

[SRFI 133]*kons knil @vec*) -> object

`(@vector-fold-right `

[SRFI 133]*kons knil @vec*) -> object

Folds *kons* over the elements of *@vec*
in increasing/decreasing order using *knil*
as the initial value.
The *kons* procedure is called with the state first
and the element second, as in SRFIs 43 and 133
(heterogeneous vectors).
This is the opposite order to that used in SRFI 1 (lists)
and the various string SRFIs.

`(@vector-map `

[SRFI 133]*f @vec*) -> @vector

`(@vector-map! `

[SRFI 133]*f @vec*) -> unspecified

`(@vector-for-each `

[SRFI 133]*f @vec*) -> unspecified

Iterate over the elements of *@vec* and apply *f*
to each, returning respectively a @vector of the results,
an undefined value with the results placed back in *@vec*,
and an undefined value with no change to *@vec*.

`(@vector-count `

[SRFI 133]*pred? @vec*) -> exact nonnegative integer

`(@vector-cumulate `

[SRFI 133]*f knil @vec*) -> @vector

Like `@vector-fold`

, but returns an @vector of partial results
rather than just the final result.

`(@vector-take-while `

[SRFI 152]*pred? @vec* -> @vector

`(@vector-take-while-right `

[SRFI 152]*pred? @vec* -> @vector

Return the shortest prefix/suffix of *@vec* all of whose elements
satisfy *pred?*.

`(@vector-drop-while `

[SRFI 152]*pred? vec* -> @vector

`(@vector-drop-while-right `

[SRFI 152]*pred? vec* -> @vector

`(@vector-index `

[SRFI 133]*pred? @vec*) -> exact nonnegative integer or #f

`(@vector-index-right `

[SRFI 133]*pred? @vec*) -> exact nonnegative integer or #f

Return the index of the first/last element of *@vec* that
satisfies *pred?*.

`(@vector-skip `

[SRFI 133]*pred? @vec*) -> exact nonnegative integer or #f

`(@vector-skip-right `

[SRFI 133]*pred? @vec*) -> exact nonnegative integer or #f

Returns the index of the first/last element of *@vec* that
does not satisfy *pred?*.

`(@vector-any `

[SRFI 133]*pred? @vec*) -> value or boolean

Returns first element from the *@vec* which
satisfies *pred?*, or `#f`

if there is no such element.
If *@vec* is empty, return `#f`

`(@vector-every `

[SRFI 133]*pred? @vec*) -> value or boolean

If all elements from *@vec* satisfy *pred?*,
return the last element. If not all do, return `#f`

.
If *@vec* is empty, return `#t`

`(@vector-partition `

[SRFI 133]*pred? @vec*) -> @vector and integer

Returns an @vector of the same type as *@vec*, but with all elements
satisfying *pred?* in the leftmost part of the vector and the other
elements in the remaining part. The order of elements is otherwise
preserved. Returns two values, the new @vector and the number of
elements satisfying *pred?*.

`(@vector-filter `

[SRFI 152]*pred? @vec* -> @vector

`(@vector-remove `

[SRFI 152]*pred? @vec* -> @vector

Return an @vector containing the elements of @vec that satisfy / do not satisfy
*pred?*.

`(@vector-set! `

[SRFI 4]*@vec i value*) -> unspecified

Sets the *i*th element of *@vec* to *value*.

`(@vector-swap! `

[SRFI 133]*@vec i j*) -> unspecified

Interchanges the *i*th and *j*th elements of *@vec*.

`(@vector-fill! `

[SRFI 133]*@vec fill* [*start* [*end*]]) -> unspecified

Fills the portion of *@vec* from *start* to *end*
with the value *fill*.

`(@vector-reverse! `

[SRFI 133]*@vec* [*start* [*end*]]) -> unspecified

Reverses the portion of *@vec* from *start* to *end*.

`(@vector-copy! `

[SRFI 133]*@to at @from* [*start* [*end*]]) -> unspecified

Copies the portion of *@from* from *start* to *end*
onto *@to*, starting at index *@at*.

`(@vector-reverse-copy! `

[SRFI 133]*@to at @from* [*start* [*end*]]) -> unspecified

The same as `@vector-copy!`

, but copies in reverse.

`(@vector-unfold! `

[SRFI 133]*f vec start end seed*) -> @vector

Like `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! `

[SRFI 133]*f vec start end seed*) -> @vector

The same as `@vector-unfold!`

, but initializes the @vector from right to left.

`(@vector->list `

[SRFI 4]*@vec* [*start* [*end*]]) -> proper-list

`(reverse-@vector->list `

[SRFI 133]*@vec* [*start* [*end*]]) -> proper-list

`(list->@vector `

[SRFI 4]*proper-list*) -> @vector

`(reverse-list->@vector `

[SRFI 133]*proper-list*) -> @vector

`(@vector->vector `

*@vec*) -> vector

`(vector->@vector `

*vec*) -> @vector

Returns a list, @vector, or heterogeneous vector with the same elements as the argument, in reverse order where specified.

`(make-@vector-generator `

*@vector*`)`

Returns a SRFI 121
generator that generates all the values of *@vector* in order.
Note that the generator is finite.

`@vector-comparator`

Variable containing a SRFI 128 comparator whose components provide ordering and hashing of @vectors.

`(write-@vector `

*vec* [ *port* ] ) -> unspecified

Prints to *port* (the current output port by default) a representation of
*@vec* in the lexical syntax explained below.

`read`

and `write`

procedures and by the program parser.
Conformance to this SRFI does not in itself require support for these
external representations.
For each value of `@`

in {
`s8`

, `u8`

,
`s16`

, `u16`

,
`s32`

, `u32`

,
`s64`

, `u64`

,
`f32`

, `f64`

,
`c64`

, `c128`

}, if the datatype `@vector`

is supported, then
the external representation of instances of the datatype
`@vector`

is `#@(`

...elements... `)`

.
For example, `#u8(0 #e1e2 #xff)`

is a
`u8vector`

of length 3 containing 0, 100 and 255;
`#f64(-1.5)`

is an `f64vector`

of length 1
containing -1.5.
Note that the syntax for float vectors conflicts with R5RS,
which parses `#f32()`

as 3 objects: `#f`

,
`32`

and `()`

. For this reason, conformance to
this SRFI implies this minor nonconformance to R5RS.
This external representation is also available in program source code.
For example, `(set! x '#u8(1 2 3))`

will set `x`

to the object `#u8(1 2 3)`

. Literal homogeneous vectors,
like heterogeneous vectors, are self-evaluating; they do not need to be quoted.
Homogeneous vectors can appear in quasiquotations but must not contain
`unquote`

or `unquote-splicing`

forms
(i.e. ``(,x #u8(1 2))`

is legal but ```
`#u8(1 ,x
2)
```

is not). This restriction is to accommodate the many Scheme
systems that use the `read`

procedure to parse programs.
To reduce its complexity, this implementation is provided only for R7RS systems.
However, making it available on R6RS systems as well as R5RS systems with bytevectors
is straightforward, requiring only a replacement library file that includes the
implementation files in the `srfi/160/base`

directory.

The library `(srfi 160 base)`

is in the repository of this SRFI.
It supports the eight procedures of SRFI 4, namely `make-@vector`

,
`@vector`

, `@vector?`

, `@vector-length`

,
`@vector-ref`

, `@vector-set!`

, `@vector->list`

,
and `list->@vector`

. These are provided
not only for the ten homogeneous vector types supported by SRFI 4,
but also the two homogeneous vector types beyond the scope of SRFI 4, namely
c64vectors and c128vectors.
In addition, the `@?`

procedure, which is not in SRFI 4, is available for all types.

The implementation depends on SRFI 4.
For systems that do not have
a native SRFI 4 implementation, the version in the
`contrib/cowan`

directory of the SRFI 4 repository may be used;
it depends only on a minimal implementation of bytevectors.

The tests are for the c64 and c128 procedures and the @? procedures only. The assumption is that tests for the underlying SRFI 4 procedures suffice for everything else.

The following files are provided:

`srfi/160/base.sld`

- R7RS`(srfi 160 base)`

library.`srfi/160/base/complex.scm`

- Complex number implementation on top of SRFI 4.`srfi/160/base/valid.scm`

- Valid value predicates.`srfi/160/base/r7rec.scm`

- Record-type definitions for R7RS.`srfi/160/base/shared-tests.scm`

- Shared tests (no dependencies).`srfi/160/base/chibi-tests.scm`

- Chibi test script wrapper.

The sample implementation is (not yet) in the repository of this SRFI.
It depends on the implementation of the `(srfi 160 base)`

library
described in the previous section.

After downloading the source, it is necessary to run the `atexpander.sh`

shell script in order to generate the individual files for the different types.
This will take `at.sld`

, for example, and create the files
`u8.sld`

, `s8.sld`

, ... `c128.sld`

.
The heavy lifting is done by `sed`

.

The following files are provided:

`atexpander.sh`

- A trivial shell script using`sed`

to expand skeleton files into their variants.`srfi/160/at.sld`

- Skeleton for Chibi libraries. Can be adapted to any R7RS system.`srfi/160/at-impl.scm`

- Skeleton for shared implementation of SRFI 160 procedures.`srfi/160/chibi-tests.scm`

- Tests for Chibi of the s16 library only. The assumption is that if s16 works, everything works.

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