For Development HEAD DRAFTSearch (procedure/syntax/module):

Next: , Previous: , Up: Core library   [Contents][Index]

6.13 Vector family

Vectors are fixed-size, O(1) accessible sequence of values. Scheme has traditionally offered a vector of arbitrary objects, which is described in Vectors.

In R7RS-large, there’re also homogeneous numeric vectors (uvectors), which can contain fixed range of numeric objects efficiently. We explain them in Uniform vectors.

Gauche also supports bitvectors, which can contain sequence of bits. See Bitvectors, for the details.

Finally, weak vectors are a vector of arbitrary objects using weak pointers. See Weak vectors.


Next: , Previous: , Up: Vector family   [Contents][Index]

6.13.1 Vectors

Builtin Class: <vector>

A vector is a simple 1-dimensional array of Scheme objects. You can access its element by index in constant time. Once created, a vector can’t be resized.

Class <vector> inherits <sequence> and you can use various generic functions such as map and fold on it. See Collection framework, and See Sequence framework.

If you keep only a homogeneous numeric type, you may be able to use SRFI-4 homogeneous vectors (see Homogeneous vectors).

R7RS defines bytevectors; in Gauche, they’re just u8vectors in gauche.uvector module (r7rs modules defines aliases. see R7RS base library).

See R7RS vectors, for additional operations on vectors.

Function: vector? obj

[R7RS base] Returns #t if obj is a vector, #f otherwise.

Function: make-vector k :optional fill

[R7RS base] Creates and returns a vector with length k. If optional argument fill is given, each element of the vector is initialized by it. Otherwise, the initial value of each element is undefined.

Function: vector obj …

[R7RS base] Creates a vector whose elements are obj ….

Function: vector-tabulate len proc

Creates a vector of length len, initializing i-th element of which by (proc i) for all i between 0 and len

(vector-tabulate 5 (^x (* x x)))
  ⇒ #(0 1 4 9 16)
Function: vector-length vector

[R7RS base] Returns the length of a vector vector.

With gauche.collection module, you can also use a method size-of.

Function: vector-ref vector k :optional fallback

[R7RS+] Returns k-th element of vector vector.

By default, vector-ref signals an error if k is negative, or greater than or equal to the length of vector. However, if an optional argument fallback is given, it is returned for such case. This is an extension of Gauche.

With gauche.sequence module, you can also use a method ref.

Function: vector-set! vector k obj

[R7RS base] Sets k-th element of the vector vector to obj. It is an error if k is negative or greater than or equal to the length of vector.

With gauche.sequence module, you can also use a setter method of ref.

Function: vector->list vector :optional start end
Function: list->vector list :optional start end

[R7RS+] Converts a vector to a list, or vice versa.

The optional start and end arguments limit the range of the source. (R7RS don’t define start and end arguments for list->vector.)

(vector->list '#(1 2 3 4 5))     ⇒ (1 2 3 4 5)
(list->vector '(1 2 3 4 5))      ⇒ #(1 2 3 4 5)
(vector->list '#(1 2 3 4 5) 2 4) ⇒ (3 4)
(list->vector (circular-list 'a 'b 'c) 1 6)
  ⇒ #(b c a b c)

With gauche.collection module, you can use (coerce-to <list> vector) and (coerce-to <vector> list) as well.

Function: reverse-list->vector list :optional start end

[R7RS vector] Without optional arguments, it returns the same thing as (list->vector (reverse list)), but does not allocate the intermediate list. The optional start and end argument limits the range of the input list.

(reverse-list->vector '(a b c d e f g) 1 5)
  ⇒ #(e d c b)
Function: vector->string vector :optional start end
Function: string->vector string :optional start end

[R7RS base] Converts a vector of characters to a string, or vice versa. It is an error to pass a vector that contains other than characters to vector->string.

The optional start and end arguments limit the range of the source.

(vector->string '#(#\a #\b #\c #\d #\e))     ⇒ "abcde"
(string->vector "abcde")                     ⇒ #(#\a #\b #\c #\d #\e)
(vector->string '#(#\a #\b #\c #\d #\e) 2 4) ⇒ ("cd")

With gauche.collection module, you can use (coerce-to <string> vector) and (coerce-to <vector> string) as well.

Function: vector-fill! vector fill :optional start end

[R7RS base] Sets all elements in a vector vector to fill.

Optional start and end limits the range of effect between start-th index (inclusive) to end-th index (exclusive). Start defaults to zero, and end defaults to the length of vector.

Function: vector-copy vector :optional start end fill

[R7RS base] Copies a vector vector. Optional start and end arguments can be used to limit the range of vector to be copied. If the range specified by start and end falls outside of the original vector, the fill value is used to fill the result vector.

(vector-copy '#(1 2 3 4 5))     ⇒ #(1 2 3 4 5)
(vector-copy '#(1 2 3 4 5) 2 4) ⇒ #(3 4)
(vector-copy '#(1 2 3 4 5) 3 7 #f) ⇒ #(4 5 #f #f)
Function: vector-copy! target tstart source :optional sstart send

[R7RS base] Copies the content of source vector into the target vector starting from tstart in the target. The target vector must be mutable. Optional sstart and send limits the range of source vector.

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-copy! v 2 '#(1 2)))
  ⇒ #(a b 1 2 e)
(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-copy! v 2 '#(1 2 3 4) 1 3))
  ⇒ #(a b 2 3 e)

An error is raised if the portion to be copied is greater than the room in the target (that is, between tstart to the end).

It is ok to pass the same vector to target and source; it always works even if the regions of source and destination are overlapping.

Function: vector-append vec …

[R7RS base] Returns a newly allocated vector whose contents are concatenation of elements of vec in order.

(vector-append '#(1 2 3) '#(a b)) ⇒ #(1 2 3 a b)
(vector-append) ⇒ #()
Function: vector-map proc vec1 vec2 …

[R7RS base] Returns a new vector, i-th of which is calculated by applying proc on the list of each i-th element of vec1 vec2 …. The length of the result vector is the same as the shortest vector of the arguments.

(vector-map + '#(1 2 3) '#(4 5 6 7))
 ⇒ #(5 7 9)

The actual order proc is called is undefined, and may change in the future versions, so proc shouldn’t use side effects affected by the order.

Note: If you use gauche.collection, you can get the same function by (map-to <vector> proc vec1 vec2 …).

Function: vector-map-with-index proc vec1 vec2 …

Like vector-map, but proc receives the current index as the first argument.

(vector-map-with-index list '#(a b c d e) '#(A B C))
 ⇒ #((0 a A) (1 b B) (2 c C))

This is what SRFI-43 calls vector-map. See Vector library (Legacy).

Note: If you use gauche.collection, you can get the same function by (map-to-with-index <vector> proc vec1 vec2 …).

Function: vector-map! proc vec1 vec2 …

[R7RS vector] For each index i, calls proc with i-th index of vec1 vec2 …, and set the result back to vec1. The value is calculated up to the minimum length of input vectors.

(rlet1 v (vector 1 2 3)
  (vector-map! ($ + 1 $) v))
  ⇒ #(2 3 4)

(rlet1 v (vector 1 2 3 4)
  (vector-map! + v '#(10 20)))
  ⇒ #(11 22 3 4)
Function: vector-map-with-index! proc vec1 vec2 …

Like vector-map!, but proc receives the current index as the first argument. This is equivalent to SRFI-43’s vector-map! (see Vector library (Legacy)).

(rlet1 v (vector 'a 'b 'c)
  (vector-map-with-index! list v))
  ⇒ #((0 a) (1 b) (2 c))
Function: vector-for-each proc vec1 vec2 …

[R7RS base] For all i below the minimum length of input vectors, calls proc with i-th elements of vec1 vec2 …, in increasing order of i.

(vector-for-each print '#(a b c))
 ⇒ prints a, b and c.
Function: vector-for-each-with-index proc vec1 vec2 …

Like vector-for-each, but proc receives the current index in the first argument.

This is equivalent to SRFI-43’s vector-for-each. See Vector library (Legacy).


Next: , Previous: , Up: Vector family   [Contents][Index]

6.13.2 Uniform vectors

Uniform vectors, or homogeneous numeric vectors, are a special type of vectors whose elements are of the same numeric type. It was introduced originally as srfi-4, revised by srfi-160, and now a part of R7RS large (as scheme.vector.@).

The @ part is actually one of the following tags, indicating the type of elements:

u8

Unsigned 8-bit integer - an exact integer between 0 and 255.

s8

Signed 8-bit integer - an exact integer between -128 and 127.

u16

Unsigned 16-bit integer - an exact integer between 0 and 65535.

s16

Signed 16-bit integer - an exact integer between -32678 and 32767.

u32

Unsigned 32-bit integer - an exact integer between 0 and 2^32 - 1.

s32

Signed 32-bit integer - an exact integer between -(2^31) and 2^31 - 1.

u64

Unsigned 64-bit integer - an exact integer between 0 and 2^64 - 1.

s64

Signed 64-bit integer - an exact integer between -(2^63) and 2^63 - 1.

f16

16-bit floating point number (10-bit mantissa and 5-bit exponent), as inexact real.

f32

IEEE single-precision floating point number as inexact real.

f64

IEEE double-precision floating point number as inexact real.

c32

Inexact complex, consists of a pair of 16-bit floating point numbers.

c64

Inexact complex, consists of a pair of IEEE single-precision floating point numbers.

c128

Inexact complex, consists of a pair of IEEE double-precision floating point numbers.

There are some advantages of using uniform vectors over normal (heterogeneous) vectors. It may be more compact than the normal vectors. Some operations (especially Gauche’s extension of vector arithmetic operations) can bypass type check and conversion of individual elements, thus be more efficient. And it is much easier and efficient to communicate with external libraries that require homogeneous array of numbers; for example, OpenGL binding of Gauche uses uniform vectors extensively.

Gauche has only a handful primitive operations on uniform vectors as a built-in, but the gauche.uvector module, or scheme.vector.@ module ((scheme vector @) library in R7RS programs), provide a complehensive set of operations. See Uniform vector library, and see R7RS uniform vectors.

Uvector classes

Abstract Class: <uvector>

The base class of uniform vector classes. It inherits <sequence> (see Sequence framework).

Builtin Class: <@vector>

{gauche.uvector} A class for @vector, where @ is one of the uvector tags (u8, s8, …). It inherits <uvector>.

It implements sequence protocol (see Sequence framework)), so you can convert a sequence of real numbers into a uvector using coerce-to, if every elements is valid for the uvector.

(use gauche.sequence)
(coerce-to <u8vector> '(1 2 3)) ⇒ #u8(1 2 3)

Uvector literals

Reader Syntax: #u8(n …)
Reader Syntax: #s8(n …)
Reader Syntax: #u16(n …)
Reader Syntax: #s16(n …)
Reader Syntax: #u32(n …)
Reader Syntax: #s32(n …)
Reader Syntax: #u64(n …)
Reader Syntax: #s64(n …)
Reader Syntax: #f16(n …)
Reader Syntax: #f32(n …)
Reader Syntax: #f64(n …)
Reader Syntax: #c32(n …)
Reader Syntax: #c64(n …)
Reader Syntax: #c128(n …)

Denotes a literal homogeneous vector.

(Note: R7RS bytevector is the same as u8vector, and can be written as #u8(…).)

#s8(3 -2 4)
#u32(4154 88357 2 323)
#f32(3.14 0.554525 -3.342)

Uvector generic operations

Function: uvector? obj

Returns #t iff obj is one of the uniform vectors. See below for predicates for specific type of uvector.

Function: uvector-length uv

Returns the length (the number of elements) of uvector uv. An error is raised if uv is not a uvector.

Type specific length procedures are provided in scheme.vector.@ and gauche.uvector (see Uniform vector library).

To get the size of the binary data the content of the uvector actually occupies, use uvector-size in gauche.uvector.

Function: uvector-ref uv k :optional fallback

Generic uvector accessor. Returns k-th element of a uniform vector uv. If k is out-of-range, fallback is returned if provided, or an error is thrown otherwise.

This is handy to write a generic code that works on any kind of uniform vector, but this is slower than the specific versions. Gauche’s compiler recognizes the specific versions of referencer and generate very efficient code for them, while this generic version becomes a normal procedure call. In inner-loop it can make a big difference.

See below for the type-specific accessors.

(setter uvector-ref) is uvector-set!.

Function: uvector-set! uv k val :optional clamp

{gauche.uvector} Generic uvector setter. Mutate k-th element of uvector uv with val. An error is thrown if k is out-of-range, or uv is immutable.

Optional clamp argument specifies the behavior when val is out of valid range. It can be #f or one of the symbols low, high, or both. See Uniform vector library, for the meanings of the clamp argument. The default is #f, which raises an error on out-of-range value.

Uvector type-specific operations

Type-specific predicates, accessors and modifiers are provided in the core library; all the rest are in scheme.vector.@ or gauche.uvector (see Uniform vector library).

Function: @vector? obj

[R7RS vector.@] {gauche.uvector} Returns #t iff obj is a @vector, #f otherwise. The @ part is one of the uvector tags (u8 etc.).

Function: @vector-ref vec k :optional fallback

[R7RS vector.@] {gauche.uvector} Returns the k-th element of @vector vec. The @ part is one of the uvector tags (u8 etc.).

If the index k is out of the valid range, an error is signaled unless an optional argument fallback is given; in that case, fallback is returned.

Note that the generic function ref can be used as well, if you import gauche.collection.

(u16vector-ref '#u16(111 222 333) 1) ⇒ 222

(use gauche.collection)
(ref '#u16(111 222 333) 1) ⇒ 222

Setter of @vector-ref is @vector-set!.

(use gauche.uvector)
(define v (u8vector 1 2 3))
(set! (u8vector-ref v 1) 99)

v ⇒ #u8(1 99 3)
Function: @vector-set! vec k n :optional clamp

[R7RS vector.@] {gauche.uvector} Sets a number n to the k-th element of @vector vec. The @ part is one of the uvector tags (u8 etc.).

Optional clamp argument specifies the behavior when n is out of valid range. It can be #f or one of the symbols low, high, or both. See Uniform vector library, for the meanings of the clamp argument. The default is #f, which raises an error on out-of-range value.

Note that the setter of the generic function ref can be used as well, if you import gauche.collection.

(let ((v (s32vector -439 852 8933)))
  (s32vector-set! v 1 4)
  v)
 ⇒ #s32vector(-439 4 8933)

(use gauche.collection)
(let ((v (s32vector -439 852 8933)))
  (set! (ref v 1) 4)
  v)
 ⇒ #s32vector(-439 4 8933)

Next: , Previous: , Up: Vector family   [Contents][Index]

6.13.3 Bitvectors

A bitvector is a sequence of bits. Each bit can be considered either an exact integer 0/1, or a boolean values #f/#t. In the former view, it is similar to a uniform vector, but it has the interface sufficiently different from uvectors and we provided it as a disjoint type.

Gauche provides a handful of procedures in the core. SRFI-178 provides comprehensive bitvector library. See Bitvector library, for the details.

Builtin class: <bitvector>

Bitvector class. Inherits <sequence>, so generic sequence opertaions can be used. (Generic ref uses bitvector-ref/int, for it matches the external representation of a bitvector.)

Reader Syntax: #*b

[SRFI-178] A bitvector literal is #* followed by zero or more binary digits 0 or 1.

#*10010010           ; bitvector of length 8
#*                   ; bitvector of length 0

A bitvector literal is delimited by one of delimiter character or an EOF.

#*10010abc           ; error
#*10001(a b c)       ; a bitvector, followed by a list

Note: With this rule, #*"..." should be read as a zero-length bitvector followed by a string, for " is a delimiter. However, Gauche used that syntax for incomplete strings (our overlook!). Since incomplete string literals is rare (incomplete strings are something that unexpectedly happen in the practical situation, but not to be used actively), we changed incomplete string literals to #**"..." since 0.9.10 (see Incomplete strings).

For the backward compatibility, the current version reads #*"..." as an incomplete string. If the reader lexical mode is warn-legacy (see Reader lexical mode), such literals are warned. We’ll gradually migrate to make #*"..." read as a bytevector followed by a string.

Function: bit->integer bit
Function: bit->boolean bit

[SRFI-178] Many bitvector operations can accept bit as a boolean (#f/#t) or an exact integer (0/1). These are utility procedures to obtain desired type. The bit argument must be either one of #f, #t, 0 or 1. They return 0/1 and #f/#t, respectively. An error is signalled if bit is other than those values.

Function: bitvector b …

[SRFI-178] Creates and returns a bitvector whose elements are b …. Each argument must be a bit (boolean or 0 or 1).

(bitvector 0 1 0 0 1 0 0 0 1) ⇒ #*010010001
(bitvector) ⇒ #*
Function: make-bitvector len :optional init

[SRFI-178] Creates and returns a bitvector with length len, and all elements being initialized by init, which must be a bit (boolean or 0 or 1).

If init is omitted, the content of the bitvector is undefined (currently we fill it with 0, but don’t count on it.)

(make-bitvector 5 #f)  ⇒ #*00000
(make-bitvector 7 1)   ⇒ #*1111111
Function: list->bitvector lis

[SRFI-178] Lis must be a list of bits (0, 1 or booleans). Returns a bitvector whose elements consist of elements of lis.

(list->bitvector '(#t #f #t #t #f))  ⇒ #*10110
(list->bitvector '(0 1 1 1 0 1 0 1)) ⇒ #*01110101
Function: string->bitvector s

[SRFI-178] If s is a valid bitvector literal (#*b... where b is either 0 or 1), returns a bitvector represented by the string. Otherwise, #f is returned.

(string->bitvector "#*1010001") ⇒ #*1010001
(string->bitvector "#*1001020") ⇒ #f

Note that this isn’t a sequence-conversion, but rather a conversion from external representation.

Function: bitvector->string bv

[SRFI-178] Convert a bitvector bv to a string representation #*b....

(bitvector->string #*1001010) ⇒ "#*1001010"

Note that this isn’t a sequence-conversion, but rather a conversion to external representation.

Function: bitvector-ref/int bv k :optional fallback
Function: bitvector-ref/bool bv k :optional fallback

[SRFI-178+] Retrieves the k-th bit of a bitvector bv as an integer or a boolean value, respectively. If k is out of range, fallback is returned if it is given, or an error is raised otherwise. The fallback argument is Gauche’s extension.

(bitvector-ref/int #*1010001 0)  ⇒ 1
(bitvector-ref/bool #*1010001 0) ⇒ #t

If you use a universal accessor ref/~, it returns the bit value as an integer (see Universal accessor).

(~ #*11001001 1) ⇒ 1
Function: bitvector-set! bv k bit

[SRFI-178] Sets the k-th bit of a bitvector bv with bit, which must be either one of 0, 1, #f or #t. An error is raised if k is out of range.

This procedure is set as the setter of bitvector-ref/int and bitvector-ref/bool. Since a bitvector is a sequence, you can also use (setter ref)/(setter ~):

(rlet1 z (make-bitvector 5 0)
  (set! (~ z 2) #t))
  ⇒ #00100
Function: bitvector-copy bv :optional start end

[SRFI-178] Returns a copy of a bitvector bv. If optional start and end indexes are given, the copy is limited in that range, where start is inclusive and end is exclusive.

(bitvector-copy #*101001000 3)   ⇒ #*001000
(bitvector-copy #*100101000 2 7) ⇒ #*01010
Function: bitvector-copy! target tstart src :optional sstart send

[SRFI-178] Copy a bitvector src into a mutable bitvector target starting from tstart, mutating target. Optional sstart and send delimits the range in src.

(rlet1 v (make-bitvector 10 0)
  (bitvector-copy! v 3 #*101101110 2 6))
  ⇒ #*0001101000

Previous: , Up: Vector family   [Contents][Index]

6.13.4 Weak vectors

A weak pointer is a reference to an object that doesn’t prevent the object from being garbage-collected. Gauche provides weak pointers as a weak vector object. A weak vector is like a vector of objects, except each object can be garbage collected if it is not referenced from objects other than weak vectors. If the object is collected, the entry of the weak vector is replaced for #f.

gosh> (define v (make-weak-vector 1))
v
gosh> (weak-vector-ref v 0)
#f
gosh> (weak-vector-set! v 0 (cons 1 1))
#<undef>
gosh> (weak-vector-ref v 0)
(1 . 1)
gosh> (gc)
#<undef>
gosh> (gc)
#<undef>
gosh> (weak-vector-ref v 0)
#f

See R7RS ephemerons, for R7RS-large way of weak pointers.

Builtin Class: <weak-vector>

The weak vector class. Inherits <sequence> and <collection>, so you can use gauche.collection (see Collection framework) and gauche.sequence (see Sequence framework).

(coerce-to <weak-vector> '(1 2 3 4))
  ⇒ a weak vector with four elements
Function: make-weak-vector size

Creates and returns a weak vector of size size.

Function: weak-vector-length wvec

Returns the length of a weak vector wvec.

Function: weak-vector-ref wvec k :optional fallback

Returns k-th element of a weak vector wvec.

By default, weak-vector-ref signals an error if k is negative, or greater than or equal to the size of wvec. However, if an optional argument fallback is given, it is returned for such case.

If the element has been garbage collected, this procedure returns fallback if it is provided, #f otherwise.

With gauche.sequence module, you can also use a method ref.

Function: weak-vector-set! wvec k obj

Sets k-th element of the weak vector wvec to obj. It is an error if k is negative or greater than or equal to the size of wec.


Previous: , Up: Vector family   [Contents][Index]


For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT