Bytevectors¶
Overview¶
Bytevectors represent blocks of binary data as fixed-length sequences of typed integer elements. Unlike vectors, which can hold any Scheme object, bytevectors are specialised for compact, efficient storage of numeric data.
Element Types
This implementation extends the standard R7RS bytevector with support for signed and unsigned integer elements of multiple widths, following the conventions of SRFI-4. Each bytevector has a fixed element type, chosen at construction time, which determines both the width of each element and whether its values are interpreted as signed or unsigned. The supported types are:
Symbol |
C type |
Minimum value |
Maximum value |
|---|---|---|---|
|
uint8_t |
0 |
255 |
|
int8_t |
-128 |
127 |
|
uint16_t |
0 |
65,535 |
|
int16_t |
-32,768 |
32,767 |
|
uint32_t |
0 |
4,294,967,295 |
|
int32_t |
-2,147,483,648 |
2,147,483,647 |
|
uint64_t |
0 |
18,446,744,073,709,551,615 |
|
int64_t |
-9,223,372,036,854,775,808 |
9,223,372,036,854,775,807 |
If no type is specified at construction, the type defaults to 'u8, which
is the standard R7RS bytevector type.
Length
The length of a bytevector is the number of elements it contains, regardless
of the underlying byte width of each element. For example, a 'u16
bytevector of length 3 contains 3 elements, each occupying 2 bytes of storage.
The length is a non-negative exact integer that is fixed at construction time
and cannot be changed. Valid indices are exact non-negative integers less than
the length, starting at index zero.
Literal Notation
Bytevectors are written using the notation #<type>(elem ...), where
<type> indicates the element type. For example:
#u8(0 10 5) ; A u8 bytevector of length 3
#s8(-1 0 1) ; An s8 bytevector of length 3
#u16(1000 2000) ; A u16 bytevector of length 2
#s32(-100000 0) ; An s32 bytevector of length 2
The standard R7RS #u8(...) notation is equivalent to the 'u8 type.
Bytevector constants are self-evaluating and do not need to be quoted in
programs.
Type Compatibility
A bytevector’s element type is fixed for its lifetime. Procedures that operate
on two bytevectors simultaneously, such as bytevector-copy! and
bytevector-append, require both bytevectors to be of the same type and will
raise an error if they are not.
Value Range Checking
All procedures that write to a bytevector validate that the value being written
falls within the valid range for the bytevector’s element type. An error is
raised if a value is out of range. For example, attempting to store -1 in
a 'u8 bytevector, or 256 in a 'u8 bytevector, will raise an error.
Space Efficiency
Bytevectors are significantly more space-efficient than vectors containing the
same values, as each element occupies exactly the number of bytes required by
its type rather than a full heap-allocated Scheme object. A 'u8 bytevector
of length 1024 occupies 1024 bytes of storage, whereas a vector of 1024 small
integers would require 1024 object pointers plus the objects themselves.
Bytevector Procedures¶
bytevector¶
- (bytevector byte ... [type])
Returns a newly allocated bytevector containing byte … as its elements. The optional type argument is a symbol specifying the element type of the bytevector; it must be one of
'u8,'s8,'u16,'s16,'u32,'s32,'u64, or's64. If omitted, the type defaults to'u8. Each byte must be an exact integer within the valid range for the specified type; an error is raised otherwise.- Parameters:
byte (integer) – Zero or more exact integers, each within the valid range for type.
type (symbol) – The element type of the bytevector. Must be one of
'u8,'s8,'u16,'s16,'u32,'s32,'u64, or's64. Defaults to'u8.
- Returns:
A new bytevector of the specified type containing byte …
- Return type:
bytevector
Example:
--> (bytevector 1 2 3) #u8(1 2 3) --> (bytevector 1 2 3 's8) #s8(1 2 3) --> (bytevector 1000 2000 3000 'u16) #u16(1000 2000 3000) --> (bytevector -1 -2 -3 's16) #s16(-1 -2 -3)
bytevector-length¶
- (bytevector-length bytevector)
Returns the number of elements in bytevector as an exact integer. Note that for multi-byte types (e.g.
'u16,'s32), this is the number of elements, not the number of underlying bytes in the backing storage.- Parameters:
bytevector (bytevector) – The bytevector to measure.
- Returns:
The number of elements in bytevector.
- Return type:
integer
Example:
--> (bytevector-length (bytevector 1 2 3)) 3 --> (bytevector-length (bytevector 1000 2000 3000 'u16)) 3 --> (bytevector-length (bytevector)) 0
bytevector-ref¶
- (bytevector-ref bytevector k)
Returns the element at index k in bytevector, where the first element is at index
0. The value is returned as an exact integer. Raises an error if k is out of range.- Parameters:
bytevector (bytevector) – The bytevector to index into.
k (integer) – The zero-based index of the element to retrieve.
- Returns:
The element at index k as an exact integer.
- Return type:
integer
Example:
--> (bytevector-ref (bytevector 1 2 3) 0) 1 --> (bytevector-ref (bytevector 1 2 3) 2) 3 --> (bytevector-ref (bytevector -1 -2 -3 's8) 0) -1
bytevector-set!¶
- (bytevector-set! bytevector k byte)
Stores byte at index k of bytevector, mutating it in place. byte must be an exact integer within the valid range for the type of bytevector. Raises an error if k is negative or out of range, or if byte is out of range for the bytevector’s type. Returns an unspecified value.
- Parameters:
bytevector (bytevector) – The bytevector to mutate.
k (integer) – The zero-based index at which to store byte.
byte (integer) – The value to store.
- Returns:
Unspecified.
Example:
--> (define bv (bytevector 1 2 3)) --> (bytevector-set! bv 1 99) --> bv #u8(1 99 3) --> (define bv16 (bytevector 100 200 300 'u16)) --> (bytevector-set! bv16 0 1000) --> bv16 #u16(1000 200 300)
make-bytevector¶
- (make-bytevector k [byte [type]])
Returns a newly allocated bytevector of k elements. If byte is given, every element is initialised to byte; otherwise every element is initialised to
0. The optional type argument is a symbol specifying the element type; it must be one of'u8,'s8,'u16,'s16,'u32,'s32,'u64, or's64. If omitted, the type defaults to'u8. byte must be within the valid range for type.Note
Because type is the third argument, creating an empty bytevector of a non-default type requires a dummy fill value of
0as the second argument, e.g.(make-bytevector 0 0 'u16).- Parameters:
k (integer) – The number of elements in the new bytevector.
byte (integer) – The value to initialise each element to. Defaults to
0.type (symbol) – The element type of the bytevector. Defaults to
'u8.
- Returns:
A new bytevector of k elements.
- Return type:
bytevector
Example:
--> (make-bytevector 4) #u8(0 0 0 0) --> (make-bytevector 4 7) #u8(7 7 7 7) --> (make-bytevector 4 0 's16) #s16(0 0 0 0) --> (make-bytevector 3 -1 's8) #s8(-1 -1 -1) --> (make-bytevector 0) #u8() --> (make-bytevector 0 0 'u16) #u16()
bytevector-copy¶
- (bytevector-copy bytevector [start [end]])
Returns a newly allocated bytevector containing the elements of bytevector between start (inclusive) and end (exclusive). The new bytevector has the same type as bytevector. start defaults to
0and end defaults to the length of bytevector.- Parameters:
bytevector (bytevector) – The bytevector to copy.
start (integer) – The index of the first element to include. Defaults to
0.end (integer) – The index past the last element to include. Defaults to the length of bytevector.
- Returns:
A new bytevector containing the specified elements.
- Return type:
bytevector
Example:
--> (bytevector-copy (bytevector 1 2 3 4 5)) #u8(1 2 3 4 5) --> (bytevector-copy (bytevector 1 2 3 4 5) 2) #u8(3 4 5) --> (bytevector-copy (bytevector 1 2 3 4 5) 1 3) #u8(2 3) --> (bytevector-copy (bytevector 100 200 300 'u16) 1 3) #u16(200 300)
bytevector-copy!¶
- (bytevector-copy! to at from [start [end]])
Copies the elements of bytevector from between start (inclusive) and end (exclusive) into bytevector to, starting at index at, mutating to in place. start defaults to
0and end defaults to the length of from. If the source and destination overlap, the copy is performed correctly as if via a temporary intermediate bytevector. to and from must be of the same bytevector type. Returns an unspecified value.- Parameters:
to (bytevector) – The destination bytevector.
at (integer) – The index in to at which to begin writing.
from (bytevector) – The source bytevector.
start (integer) – The index of the first element in from to copy. Defaults to
0.end (integer) – The index past the last element in from to copy. Defaults to the length of from.
- Returns:
Unspecified.
Example:
--> (define bv (bytevector 1 2 3 4 5)) --> (bytevector-copy! bv 1 (bytevector 10 20 30)) #void --> bv #u8(1 10 20 30 5) --> (bytevector-copy! bv 0 (bytevector 10 20 30) 1 3) #void --> bv #u8(20 30 20 30 5)
bytevector-append¶
- (bytevector-append bytevector ...)
Returns a newly allocated bytevector whose elements are the concatenation of the elements of all bytevector arguments, in order. All arguments must be bytevectors of the same type. If no arguments are provided, returns an empty
u8bytevector.- Parameters:
bytevector (bytevector) – Zero or more bytevectors of the same type to concatenate.
- Returns:
A new bytevector containing all elements of all bytevector arguments.
- Return type:
bytevector
Example:
--> (bytevector-append (bytevector 1 2) (bytevector 3 4)) #u8(1 2 3 4) --> (bytevector-append (bytevector 100 200 'u16) (bytevector 300 400 'u16)) #u16(100 200 300 400) --> (bytevector-append) #u8()
utf8->string¶
- (utf8->string bytevector [start [end]])
Decodes the bytes of bytevector between start (inclusive) and end (exclusive) and returns the corresponding string. bytevector must be a
u8bytevector. start and end are byte offsets. start defaults to0and end defaults to the length of bytevector.- Parameters:
bytevector (bytevector) – A
u8bytevector containing UTF-8 encoded bytes.start (integer) – The byte offset of the first byte to decode. Defaults to
0.end (integer) – The byte offset past the last byte to decode. Defaults to the length of bytevector.
- Returns:
A string decoded from the specified bytes.
- Return type:
string
Example:
--> (utf8->string (bytevector 104 101 108 108 111)) "hello" --> (utf8->string (bytevector 104 101 108 108 111) 1) "ello" --> (utf8->string (bytevector 104 101 108 108 111) 1 3) "el"
string->utf8¶
- (string->utf8 string [start [end]])
Encodes the characters of string between start (inclusive) and end (exclusive) and returns the corresponding
u8bytevector. start and end are byte offsets into the underlying UTF-8 representation of string. start defaults to0and end defaults to the byte length of string.- Parameters:
string (string) – The string to encode.
start (integer) – The byte offset of the first byte to encode. Defaults to
0.end (integer) – The byte offset past the last byte to encode. Defaults to the byte length of string.
- Returns:
A
u8bytevector containing the UTF-8 encoding of the specified portion of string.- Return type:
bytevector
Example:
--> (string->utf8 "hello") #u8(104 101 108 108 111) --> (string->utf8 "hello" 1) #u8(101 108 108 111) --> (string->utf8 "hello" 1 3) #u8(101 108)