This is a proposal for a simple numeric vector API. The conceit is that we provide what appear to be a set of specialized numeric-only vectors, but there really is only one underlying type, the bytevector. This makes it easy to see a single byte sequence in a variety of ways, not just as a homogeneous vector.
This design subsumes SRFI 4 with the exception of its type predicates. It differs from related designs such as SRFI 63, SRFI 66, and 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 are the numeric-vector analogues of the R7RS-small vector API.
A <type> consists of a <principal type> followed by an <endianism>.
The <principal type> values are:
The <endianism> values are:
Endianism is not applicable to the u8 and s8 types. Thus there are 3 * 14 - 4, or 38, representation types altogether.
(make-<type>vector k [ fill ])
Returns a newly allocated bytevector of length k * b, where b is the number of bytes specified by <type>. Fill is converted to a binary value according to <type> and used to fill the bytevector; the default is implementation-defined. An error is signaled if fill cannot be accurately converted to <type>.
(<type>vector v ... )
Returns a newly allocated bytevector of length k * b, where k is the number of arguments to the procedure and b is the number of bytes specified by <type>. It is filled with the binary values resulting from encoding the v arguments according to <type>. An error is signaled if an argument cannot be accurately converted to <type>.
There are no <type>vector? predicates, as bytevector? is sufficient.
(bytevector-empty? bytevector)
Returns #t iff bytevector has length 0. This procedure is not specialized for different numeric types.
(<type>vector-ref bytevector k)
Returns a Scheme number corresponding to the binary value encoded according to <type> beginning at offset k * b in bytevector, where b is the number of bytes specified by <type>. 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.
Since bytevector-u8-ref is defined in the small language, it is excluded here.
(<type>vector-set! bytevector k v)
Converts v to a binary value encoded according to <type> and places it into bytevector beginning at offset k * b, where b is the number of bytes specified by <type>. This procedure treats bytevector as a uniformly typed vector. An error is signaled if v cannot be accurately 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. An error is signaled if v cannot be accurately converted to <type>.
Since bytevector-u8-set! is defined in the small language, it is excluded here.
(vector-><type>vector vector [start [ end ] ])
(list-><type>vector list)
Returns a newly allocated bytevector which, when viewed as a <type>vector, has the same elements as vector or list. An error is signaled if an element of vector or list cannot be accurately converted to <type>.
(vector-><type>vector! bytevector at vector [start [ end ] ])
Writes the elements of vector from start to end into bytevector starting at at. An error is signaled if an element of vector cannot be accurately converted to <type>.
(list-><type>vector! list at)
Writes the elements of list into bytevector starting at at. An error is signaled if an element of vector or list cannot be accurately converted to <type>.
(<type>vector->vector bytevector [ start [ end ] ])
(<type>vector->list bytevector [ start [ end ] ])
Returns a newly allocated vector or list with the elements of bytevector from start to end when viewed as a <type>vector.
(<type>vector->vector! vector at bytevector [start [ end ] ])
Writes the elements of bytevector when viewed as a <type>vector from start to end into vector starting at at.
(<type>vector-length bytevector)
Returns the length of bytevector divided by b, where b is the number of bytes specified by <type>, and rounded toward zero.
(<type>vector-copy [ [ start ] end ] )
These procedures are equivalent to calling bytevector-copy with the start and end arguments multiplied by b, where b is the number of bytes specified by <type>.
(<type>vector-copy! to at from [ [ start ] end ] )
These procedures are equivalent to calling bytevector-copy! with the start, end, and at arguments multiplied by b, where b is the number of bytes specified by <type>.
There are no <type>vector-append procedures, as bytevector-append is sufficient.
(bytevector-concat list-of-bytevector)
Returns the result of concatenating the bytevectors which are members of list-of-bytevectors. This procedure is not specialized for different numeric types.
(<type>vector-fill! bytevector fill [ [ start ] end ] )
Stores fill in the elements of bytevector viewed as a <type>vector from start to end. An error is signaled if fill cannot be accurately converted to <type>.
(<type>vector-map proc bytevector1 bytevector2 ...)
Returns a newly allocated bytevector which, when viewed as a <type>vector, contains the results of applying proc to the elements of the bytevectors when viewed as <type>vectors.
(<type>vector-for-each proc bytevector1 bytevector2 ...)
Applies proc to the elements of the bytevectors when viewed as <type>vectors. Returns an unspecified value.
See the procedures of VectorsCowan, with the exceptions of the ones defined here.
For mapping C structs onto bytevectors, see StructuresCowan or StructuresTaylan.
This syntax-rules macro by Ian Price will be helpful in implementing lots of similar but not identical procedures for the 38 types.