This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home.
Source for wiki BytevectorsCowan version 1
author
cowan
comment
ipnr
127.11.51.1
name
BytevectorsCowan
readonly
0
text
This is a proposal for a bytevector API whose procedures allow a bytevector to be viewed as one of several kinds of numeric vectors. This design subsumes [http://srfi.schemers.org/srfi-4/srfi-4.html SRFI 4], except that users cannot distinguish different types of numeric vectors by predicates, since they are all bytevectors. It differs from related designs such as [http://srfi.schemers.org/srfi-63/srfi-63.html SRFI 63], [http://srfi.schemers.org/srfi-66/srfi-66.html SRFI 66], and [http://www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-3.html R6RS] in that each procedure listed below actually represents many procedures, one for each defined representation type. This makes for a ''lot'' of procedures, but many of them can be easily inlined by even a very dumb compiler, providing high efficiency. The procedures provided in the present proposal are the numeric-vector analogues of the R7RS-small vector API.
== Representation types ==
A <type> consists of a <principal type> followed by an <endianism>.
The <principal type> values are:
`u8`::
unsigned 8-bit integer
`s8`::
signed 8-bit integer
`u16`::
unsigned 16-bit integer
`s16`::
signed 16-bit integer
`u32`::
unsigned 32-bit integer
`s32`::
signed 32-bit integer
`u64`::
unsigned 64-bit integer
`s64`::
signed 64-bit integer
`u128`::
unsigned 128-bit integer
`s128`::
signed 128-bit integer
`f32`::
32-bit float
`f64`::
64-bit float
`c64`::
64-bit complex number (two 32-bit floats, real followed by imaginary)
`c128`::
128-bit complex number (two 64-bit floats, real followed by imaginary)
The <endianism> values are:
(empty)::
Native representations (system-dependent)
`le`::
Little-endian (for float and complex, IEEE format)
`be`::
Big-endian (for float and complex, IEEE format)
Endianism is not applicable to the `u8` and `s8` types. Thus there are 3 * 14 - 4, or 38, representation types altogether.
The `s` and `u` types correspond to limited ranges of exact integers, the `f` types to limited ranges of inexact real numbers, and the `c` types to limited ranges of inexact complex numbers.
The number of bytes occupied by a representation type is the number of bits expressed in its name divided by 8. This value is designated by ''b'' in the descriptions of procedures.
== Constructors ==
`(make-<type>-bytevectorvector `''k'' [ ''fill'' ]`)`
Returns a newly allocated bytevector of length ''k * b''.''Fill'' is converted to a binary value according to `<type> and used to fill the bytevector; if ''fill'' is not specified, the values of the elements are unspecified. It is an error if ''fill'' cannot be converted to <type>.
`(<type>-bytevector ` ''v'' ... `)`
Returns a newly allocated bytevector of length ''k * b'', where ''k'' is the number of arguments to the procedure. It is filled with the binary values resulting from encoding the ''v'' arguments according to <type>. It is an error if an argument cannot be converted to <type>.
== Selectors ==
`(<type>-bytevector-ref` ''bytevector k''`)`
Returns a Scheme number corresponding to the binary value encoded according to <type> beginning at offset ''k * b'' in ''bytevector''. This procedure treats ''bytevector'' as a uniformly typed vector.
`(bytevector-<type>-ref` ''bytevector k''`)`
Returns a Scheme number corresponding to the binary value encoded according to <type> beginning at offset ''k'' in ''bytevector''. This procedure treats ''bytevector'' as potentially containing more than one type.
Note that `bytevector-u8-ref` is defined in the small language.
== Mutators ==
`(<type>-bytevector-set!` ''numvector k v''`)`
Converts ''v'' to a binary value encoded according to <type> and places it into ''bytevector'' beginning at offset ''k * b''. This procedure treats ''bytevector'' as a uniformly typed vector. It is an error if ''v'' cannot be converted to <type>.
`(bytevector-<type>-set!` ''bytevector k v''`)`
Converts ''v'' to a binary value encoded according to <type> and places it into ''bytevector'' beginning at offset ''k''. This procedure treats ''bytevector'' as potentially containing more than one type. It is an error if ''v'' cannot be converted to <type>.
Note that `bytevector-u8-set!` is defined in the small language.
== Conversions to numeric vectors ==
It is an error if a value being used to fill an element of a <type>vector cannot be converted to <type>, or if ''start'' (inclusive), ''end'' (inclusive), or ''at'' are out of range, or if an existing bytevector is being overflowed.
`(vector-><type>-bytevector `''vector'' [''start'' [ ''end'' ] ]`)`
Returns a newly allocated bytevector of length ''end * b - start * b'', filled with the corresponding elements of ''vector''.
`(list-><type>-bytevector `''list''`)`
Returns a newly allocated bytevector whose length is the length of ''list'' times ''b'', filled with the elements of ''list''.
`(vector-><type>-bytevector! `''bytevector at vector'' [''start'' [ ''end'' ] ]`)`
Writes the elements of ''vector'' from ''start'' to ''end'' into ''bytevector'' starting at ''at''.
`(list-><type>-bytevector! `''list bytevector at''`)`
Writes the elements of ''list'' into ''bytevector'' starting at ''at''.
== Conversions from numeric vectors ==
It is an error if ''start'' (inclusive), ''end'' (inclusive), or ''at'' are out of range, or if an existing vector is being overflowed.
`(<type>-bytevector->vector `''bytevector'' [ ''start'' [ ''end'' ] ]`)`
`(<type>-bytevector->list `''bytevector'' [ ''start'' [ ''end'' ] ]`)`
Returns a newly allocated vector or list of length ''end - start'' with the elements of ''bytevector'' from ''start * b'' to ''end * b''.
`(<type>-bytevector->vector! `''vector at bytevector'' [''start'' [ ''end'' ] ]`)`
Writes the elements of ''bytevector'' from ''start * b'' to ''end * b'' into ''vector'' starting at ''at''.
== The whole numeric vector ==
`(<type>-bytevector-length ` ''bytevector''`)`
Returns the length of ''bytevector / b'', rounded toward zero.
`(<type>-bytevector-fill! `''bytevector fill'' [ [ ''start'' ] ''end'' ] `)`
Stores ''fill'' in the elements of ''bytevector'' viewed as a <type>vector from ''start * b'' to ''end * b''. An error is signaled if ''fill'' cannot be converted to <type>.
== Mapping ==
`(<type>-bytevector-map `''proc bytevector'' ...`)`
Returns a newly allocated bytevector which contains the results of applying ''proc'' to the elements of the ''bytevectors'' in an unspecified order.
`(<type>-bytevector-map! `''proc output-bytevector bytevector'' ...`)`
Returns a newly allocated bytevector which contains the results of applying ''proc'' to the elements of the ''bytevectors'' in an unspecified order. Returns an unspecified value.
`(<type>-bytevector-for-each `''proc bytevector'' ...`)`
Applies ''proc'' to the elements of the ''bytevectors'' in order from first to last. Returns an unspecified value.
== Extended numeric vector API ==
See the procedures of VectorsCowan, with the exceptions of the ones defined here.
== Structured representation types ==
For mapping C structs onto bytevectors, see StructuresCowan or [https://gitorious.org/taylan-guile/bytestructures/source/0a5426d6b5a6bea66f0f6eea02690c22e11e251a: StructuresTaylan].
== Packaging ==
Since there are a great many procedures, it makes sense to factor this into separate libraries. Most programs won't require all the representation types, so factoring horizontally into 38 libraries based on that is a simple approach. If the result is still too large, then we can factor vertically based on expected uses for the function.
== Implementation ==
[https://gist.github.com/ijp/1e0e67ff93c486f66fc8 This syntax-rules macro by Ian Price] will be helpful in implementing lots of similar but not identical procedures for the 38 types.
time
2014-09-25 09:39:17
version
1