Data and Aggregate Types

The current value space contains booleans, exact and inexact numbers, characters, symbols, strings, the empty list, pairs, vectors, bytevectors, procedures, and escape continuations.

When this matters

Choose the smallest value shape that communicates the job. Use an atom for one fact, a proper list for sequential data, a vector for indexed mutable slots, or a bytevector for a fixed-length block of bytes.

See it run

LISPEX
(list (vector? #(1 2)) (bytevector? #u8(1 2)) (pair? (cons 1 2)))

Observed result

OUTPUT
(#t #t #t)

Read the example

The example asks three predicates about three different aggregate values. Each constructor creates the documented kind of value, so the result is a list of three true booleans.

cons joins two values into one pair. Put a list on the right and the list grows by one, so (cons 1 (list 2 3)) is (1 2 3). Put anything else there and you get a pair that is not a list, so (cons 1 2) is (1 . 2). pair? is the question of whether a value is that pair.

When the shape is mostly fixed and only a few slots need filling, use quasiquote. Write the template after a backtick and put a comma where a value goes. One comma drops a single value into that slot, and ,@ opens a list out across several slots.

LISPEX
(define x 7)
(define ys (list 2 3))

`(a ,x ,@ys b)

Observed result

OUTPUT
(a 7 2 3 b)

,@ only works where list elements go. Alone anywhere else it is E130.

How to reason about it

  • Pairs, strings, and bytevectors are immutable in the current profile, while vectors and lexical cells are mutable.
  • Quoted aggregate data is immutable, and constructors create runtime aggregates with the documented identity rules.
  • Improper and cyclic structures are distinguished from proper lists, and deep equality terminates on cycles.

Choose quickly

Value familyTypical spellingMutation in the current profile
atoms#t, 42, 2/3, name, #\\anot applicable
list / pair(list 1 2), (cons 1 2)immutable
string"hello"immutable
vector#(1 2) or (vector 1 2)mutable slots
bytevector#u8(1 2)immutable
procedure(lambda (x) x)a callable value whose body is not data

A common mistake

Complex numbers, ports, records, and mutable pairs or strings are outside the current profile.

Current boundaries

  • Internal outcomes, signals, and internal markers for uninitialized cells are not guest values.

Keep going

List and Aggregate Procedures gives constructors and accessors. Equality explains identity versus structural comparison.

List and aggregate procedures · Equality