A sequence is a generalized array or list:
Zero or more values treated as a compound value.
Sequences have certain common operations including indexing and iteration.
(Technical note: Sequences generally implement the
interface, but Kawa will also treat strings and native
Java arrays as sequences.)
In traditional Lisp-family languages, the list is the
most important kind of sequence.
(Don’t confuse Java’s
List interface with Kawa’s use of the
word list. They’re related, in that a Kawa “list” implements
List interface, so any list is also
but not vice versa.)
A list is implemented as a chain of linked pairs. You can create a constant list by quoting a parenthesized list:
'(3 4 (10 20 30) "a string")
See Lists for details and operations.
A vector is a sequence that is implemented by storing the elements side-by-side in memory. A vector uses less space than a list of the same length, and is generally more efficient than a list.
To create a vector you can use a bracketed list:
(! vec1 ['A 'B 'C 'D 'E 'F])
This creates a vector of 6 symbols and binds it to
To select an element you can use the traditional
(vector-ref vec1 3) ⇒ 'D
Alternatively, in Kawa you can use function-call notation:
(vec1 3) ⇒ 'D
You can also create a vector using the traditional
(! vec2 (vector 'A 'B 'C 'D 'E 'F))
There is one important difference between
You can modify
vec2 by changing some or all of its elements.
You can’t do that for
(We say that
vec1 is an immutable or constant vector,
vec1 is a mutable or modifiable vector.)
To change an element use either the traditional
procedure, or function-call notation:
(vector-set! vec2 2 'Y) (set! (vec2 4) 'Z) vec2 ⇒ ['A 'B 'Y 'D 'Z 'F] (vector-set! vec1 2 'Y) ⇒ throws exception
See Vectors for details and operations.
You can use function-call notation to index a generalized sequence,
whether it is a list, vector, any
native Java array, or string:
((list 'A 'B 'C 'D) 2) ⇒ 'C ("abcdef" 3) ⇒ ⇒ (! iarr (float 1.5 3 4.5]) ;; native Java array (iarr 2) ⇒ 4.5
Note that indexing a list with an index
i will be slow, since it
has to step through the list
i times. (So don’t do that!)
A range is a sequence of numbers in order, spaced uniformly apart. Usually, these are (exact) integers that increase by one. The usual notation is:
This is the sequence of integers starting with the integer
(inclusive) and ending with the integer
[3 <: 7] is the sequence
[3 4 5 6].
<:’ is a keyword; the
< is a mnemonic for the
the set of integers that are
< the end value 6.
You can also use
<=: if you want to include the upper bound:
[4 <=: 8] is
[4 5 6 7 8].
You can use
>: for a decreasing range.
[5 >=: 1] or
[5 >: 0] both evaluate to
[5 4 3 2 1].
You can also specifify a step value:
[1 by: 2 <=: 9],
which evaluates to
[1 3 5 7 9].
If an index is a sequence of integers, the result is a new sequence (of the same type) selecting only the elements matching the index values. For example:
(vec1 [3 5 2])#(D F C)
((V1 V2) I) is
(V1 (V2 I)).
You can use a range to create a slice - a contiguous subset of a list.
(vec1 [2 <: 6])#(C D E F)
A range is different from a vector integer in that you can use a range as the index in the LHS of a set!:
(set! (vec1 [2 <: 4]) #(a b c d e))#|kawa:5|#
vec1#(A B a b c d e E F)
Notice how the number of replaced elements can be different then the number of elements in the replacement value. I.e. you can do insertion and deletion this way.
(! str1 (string-copy "ABCDEF"))#|kawa:8|#
(set! (str1 [2 <: 5]) "98")AB98F