1.1.1.3 Seqs Tutorial

A seq (pronounced “seek”) is an ordered collection of elements, accessed by index rather than by value, like a CL vector.

Seq indexing is 0-origin, like indexing of CL sequences (cl:elt etc.).

Seq creation can be done with empty-seq or the seq constructor macro. A subform whose car is $ causes seq to splice in a subsequence:

> (empty-seq)
#[ ]
> (defparameter q1 (seq 1 2 'a))
Q1
> q1
#[ 1 2 A ]
> (defparameter q2 (seq "x" ($ q1) "y"))
Q2
> q2
#["x" 1 2 A "y"]

Characters in seqs are treated specially when printing. Runs of two or more characters are printed as substrings marked by #$; if the seq consists entirely of characters, it is printed as a string preceded by #:

> (seq 1 #\h #\i 2)
#[ 1 #$"hi" 2 ]
> (seq #\h #\e #\l #\l #\o)
#"hello"
> (seq ($ "world"))
#"world"

Seqs have operations to access, add, and remove elements at the ends:

> (first q1)
1
T
> (last q1)
A
T
> (with-first q1 3)
#[ 3 1 2 A ]
> (with-last q1 7)
#[ 1 2 A 7 ]
> (less-first q2)
#[ 1 2 A "y" ]
> (less-last q2)
#[ "x" 1 2 A ]

For indexing purposes, a seq is like a map whose keys are integers. Indexing is done with @ (or lookup):

> ( q1 2)
A
T
> ( q1 17)
NIL
NIL

As you see, we again use a second value to indicate that the index was in bounds. Like maps, seqs allow you to specify the default to be returned for an out-of-bounds index:

> (setq q2 (with-default q2 0))
#[ "x" 1 2 A "y" ]/0
> ( q2 47)
0
NIL

There are two different ways to get a new element into a seq: with updates an element at a specific index (it can also be used to append an element); insert inserts an element at the given index:

> (with q1 1 7)
#[ 1 7 A ]
> (insert q1 1 7)
#[ 1 7 2 A ]
> (with q1 3 42)
#[ 1 2 A 42 ]

If with is given an out-of-bounds index, it extends the sequence as needed by inserting copies of the default:

> (with q2 8 "yow!")
#[ "x" 1 2 A "y" 0 0 0 "yow!" ]/0

To delete the element at a given index, use less:

> (less q1 1)
#[ 1 A ]

Other interesting operations on seqs are subseq and concat:

> (defparameter q3 (concat q1 q2))
Q3
> q3
#[ 1 2 A "x" 1 2 A "y" ]
> (subseq q3 1 5)
#[ 2 A "x" 1 ]

Seqs also support the generic CL sequence operations find, position, etc. (Be sure to call the versions of these functions whose names are in the fset2: package.)