The Puffin Standard Library

Small but mighty: everything you need for lists, recursion, higher-order functions, pattern matching over ADTs, assoc-list environments, graphs, and interpreters — and deliberately nothing more. 130 functions in three layers: compiler intrinsics, runtime primitives (one C implementation, one reference implementation, one VM implementation, kept in lockstep by the manifest), and a prelude written in Puffin itself, injected only when mentioned. New to the language? Start with the tutorial.

130 functions 136 examples, all machine-verified types as the checker sees them

This page is generated — edit tools/gen-stdlib-html.rkt, the manifest doc lines in src/stdlib.rkt, or the ;;> doc comments in src/prelude.puf, never this HTML — and regenerate with racket tools/gen-stdlib-html.rkt. Every example was executed against the reference interpreter (typechecker included) when the page was built; the ;; output comments are copied from what actually ran. Every snippet pastes straight into the web playground.

Types are gradual (see the tutorial): _ is the unannotated "any" type, lower-case letters are type variables, and (-> _ ... _) on an entry means it is untyped — the checker derives that shape from the arity. (Mut ...) marks the mutable collection flavors. Special formsdefine, match, let, define-type, quasiquote, … — are the language, not the library: see docs/LANGUAGE.md and the tutorial.

How do I…

The idioms a PL course leans on daily — each one verified, like everything else on this page.

Numbers & arithmetic

61-bit fixnums are the numbers (see the tutorial): arithmetic compiles to arithmetic, division by zero is checked, and there are no floats, bignums, or rationals.

+ (-> Int Int Int)intrinsic

Fixnum addition; n-ary in source, associating left.

(println (+ 1 2 3))   ;; 6
- (-> Int Int Int)intrinsic

Fixnum subtraction; unary (- n) negates.

(println (- 10 4))
(println (- 5))
;; prints:
;;   6
;;   -5
* (-> Int Int Int)intrinsic

Fixnum multiplication; n-ary in source, associating left.

(println (* 6 7))   ;; 42
< (-> Int Int Bool)intrinsic

Is the first integer strictly smaller?

(println (< 1 2))   ;; #t
<= (-> Int Int Bool)intrinsic

Is the first integer smaller or equal?

(println (<= 2 2))   ;; #t
> (-> Int Int Bool)intrinsic

Is the first integer strictly larger?

(println (> 1 2))   ;; #f
>= (-> Int Int Bool)intrinsic

Is the first integer larger or equal?

(println (>= 3 2))   ;; #t
quotient (-> Int Int Int)primitive

Integer division truncated toward zero (checked: nonzero divisor).

(println (quotient 7 2))
(println (quotient -7 2))
;; prints:
;;   3
;;   -3
remainder (-> Int Int Int)primitive

Integer remainder (checked: nonzero divisor).

(println (remainder 7 2))
(println (remainder -7 2))
;; prints:
;;   1
;;   -1
modulo (-> Int Int Int)primitive

Integer modulus; the result's sign follows the divisor (checked).

(println (modulo 7 3))
(println (modulo -7 3))
;; prints:
;;   1
;;   2
abs (-> Int Int)prelude

Absolute value.

(println (abs (- 7)))   ;; 7
min (-> Int Int Int)prelude

The smaller of two integers.

(println (min 3 9))   ;; 3
max (-> Int Int Int)prelude

The larger of two integers.

(println (max 3 9))   ;; 9
add1 (-> _ _)prelude

n + 1.

(println (add1 41))   ;; 42
sub1 (-> _ _)prelude

n - 1.

(println (sub1 43))   ;; 42
zero? (-> Int Bool)prelude

Is n zero?

(println (zero? 0))   ;; #t
even? (-> Int Bool)prelude

Is n even?

(println (even? 4))   ;; #t
odd? (-> Int Bool)prelude

Is n odd?

(println (odd? 4))   ;; #f
bitwise-and (-> Int Int Int)primitive

Bitwise AND of two integers.

(println (bitwise-and 12 10))   ;; 8
bitwise-ior (-> Int Int Int)primitive

Bitwise inclusive OR of two integers.

(println (bitwise-ior 12 10))   ;; 14
bitwise-xor (-> Int Int Int)primitive

Bitwise exclusive OR of two integers.

(println (bitwise-xor 12 10))   ;; 6
arithmetic-shift (-> Int Int Int)primitive

Shift left (positive count) or right (negative count).

(println (arithmetic-shift 1 4))
(println (arithmetic-shift 16 -2))
;; prints:
;;   16
;;   4
fixnum? (-> a Bool)primitive

Is this value an integer?

(println (fixnum? 42))
(println (fixnum? "42"))
;; prints:
;;   #t
;;   #f

Booleans & equality

Only #f is false. eq? is identity; equal? is structural over pairs, vectors, strings, ADT instances, and immutable collections.

eq? (-> a b Bool)intrinsic

Identity equality: fixnums, booleans, symbols, or the same heap object. Use equal? for structural comparison.

(println (eq? 'a 'a))
(println (eq? (list 1) (list 1)))
;; prints:
;;   #t
;;   #f
equal? (-> a b Bool)primitive

Structural equality over pairs, vectors, and strings; identity otherwise.

(println (equal? (list 1 2) (list 1 2)))   ;; #t
not (-> a Bool)intrinsic

Logical negation: #t exactly when v is #f (only #f is false).

(println (not #f))   ;; #t
boolean? (-> a Bool)primitive

Is this value #t or #f?

(println (boolean? #f))   ;; #t

Pairs & lists

Pairs are immutable (no set-car!); lists are '()-terminated chains of pairs, and the everyday data structure.

cons (-> a b (Pairof a b))primitive

Allocate a pair of two values.

(println (cons 1 2))
(println (cons 1 (cons 2 '())))
;; prints:
;;   (1 . 2)
;;   (1 2)
car (-> (Pairof a b) a)primitive

First component of a pair (checked).

(println (car (list 1 2 3)))   ;; 1
cdr (-> (Pairof a b) b)primitive

Second component of a pair (checked).

(println (cdr (list 1 2 3)))   ;; (2 3)
pair? (-> a Bool)primitive

Is this value a pair?

(println (pair? (cons 1 2)))   ;; #t
null? (-> a Bool)primitive

Is this value the empty list '()?

(println (null? '()))
(println (null? (list 1)))
;; prints:
;;   #t
;;   #f
list? (-> _ _)prelude

Is v a proper list — a chain of pairs ending in '()?

(println (list? (list 1 2)))
(println (list? (cons 1 2)))
;; prints:
;;   #t
;;   #f
length (-> (List a) Int)prelude

The number of elements in a list.

(println (length (list 'a 'b 'c)))   ;; 3
append (-> (List a) (List a) (List a))prelude

A list of xs's elements followed by ys's elements.

(println (append (list 1 2) (list 3 4)))   ;; (1 2 3 4)
reverse (-> (List a) (List a))prelude

The list in reverse order.

(println (reverse (list 1 2 3)))   ;; (3 2 1)
first (-> (List a) a)prelude

The first element of a list (car).

(println (first (list 1 2 3)))   ;; 1
second (-> (List a) a)prelude

The second element of a list.

(println (second (list 1 2 3)))   ;; 2
third (-> (List a) a)prelude

The third element of a list.

(println (third (list 1 2 3)))   ;; 3
rest (-> (List a) (List a))prelude

Everything after the first element (cdr).

(println (rest (list 1 2 3)))   ;; (2 3)
last (-> (List a) a)prelude

The final element of a nonempty list.

(println (last (list 1 2 3)))   ;; 3
list-ref (-> (List a) Int a)prelude

The i-th element of a list, 0-based (checked).

(println (list-ref (list 'a 'b 'c) 1))   ;; b
take (-> (List a) Int (List a))prelude

The first n elements of a list.

(println (take (list 1 2 3 4) 2))   ;; (1 2)
drop (-> (List a) Int (List a))prelude

The list without its first n elements.

(println (drop (list 1 2 3 4) 2))   ;; (3 4)
range (-> Int Int (List Int))prelude

The integers a, a+1, ..., b-1, as a list.

(println (range 0 5))   ;; (0 1 2 3 4)
member (-> a (List a) _)prelude

The tail of the list starting at the first equal? occurrence of v, or #f.

(println (member 2 (list 1 2 3)))
(println (member 9 (list 1 2 3)))
;; prints:
;;   (2 3)
;;   #f
assoc (-> a (List (Pairof a b)) _)prelude

The first pair whose car is equal? to k, or #f — assoc-list lookup.

(println (assoc 'b (list (cons 'a 1) (cons 'b 2))))   ;; (b . 2)
index-of (-> (List a) a Int)prelude

The 0-based position of the first equal? occurrence of v, or #f.

(println (index-of (list 'a 'b 'c) 'b))   ;; 1
remove (-> a (List a) (List a))prelude

The list without its first equal? occurrence of v.

(println (remove 2 (list 1 2 3 2)))   ;; (1 3 2)

Higher-order functions

Closures are first-class and so are the intrinsics: (foldl + 0 xs) and (sort xs <) both work.

map (-> (-> a b) (List a) (List b))prelude

Apply f to every element, collecting the results in order.

(println (map add1 (list 1 2 3)))   ;; (2 3 4)
filter (-> (-> a Bool) (List a) (List a))prelude

The elements for which p holds, in order.

(println (filter even? (range 0 10)))   ;; (0 2 4 6 8)
foldl (-> (-> a b b) b (List a) b)prelude

Fold left to right: acc becomes (f x acc) for each element x.

(println (foldl + 0 (list 1 2 3 4)))   ;; 10
foldr (-> (-> a b b) b (List a) b)prelude

Fold right to left: (f x1 (f x2 (... acc))).

(println (foldr cons '() (list 1 2 3)))   ;; (1 2 3)
andmap (-> (-> a Bool) (List a) Bool)prelude

Does p hold for every element? (#t on the empty list.)

(println (andmap even? (list 2 4 6)))   ;; #t
ormap (-> (-> a Bool) (List a) Bool)prelude

The first truthy (p x) going left to right, or #f.

(println (ormap odd? (list 2 4 5)))   ;; #t
map2 (-> _ _ _ _)prelude

Map a two-argument function over two lists in lockstep.

(println (map2 + (list 1 2 3) (list 10 20 30)))   ;; (11 22 33)
append-map (-> _ _ _)prelude

Map f over the list and append the resulting lists.

(println (append-map (lambda (x) (list x x)) (list 1 2)))   ;; (1 1 2 2)
filter-map (-> _ _ _)prelude

Map f over the list, keeping only the truthy results.

(println (filter-map (lambda (x) (if (even? x) (* x x) #f)) (list 1 2 3 4)))   ;; (4 16)
findf (-> (-> a Bool) (List a) _)prelude

The first element for which p holds, or #f.

(println (findf even? (list 1 3 4 5)))   ;; 4
partition (-> _ _ _)prelude

A pair of lists: the elements passing p, and the elements failing it.

(println (partition even? (list 1 2 3 4)))   ;; ((2 4) 1 3)
sort (-> (List a) (-> a a Bool) (List a))prelude

Sort a list by the given strict ordering (stable merge sort).

(println (sort (list 3 1 2) <))   ;; (1 2 3)
apply (-> _ _ _)prelude

Call f with the list's elements as its arguments (up to five).

(println (apply max (list 3 9)))   ;; 9

Vectors

Fixed-length mutable arrays with O(1) checked indexing.

make-vector (-> Int (Mut (Vec _)))primitive

Allocate a vector of n slots, initialized to 0.

(println (make-vector 3))   ;; #(0 0 0)
vector-ref (-> (Vec a) Int a)primitive

Fetch a slot (checked: type and bounds; dynamic index).

(println (vector-ref (vector 'a 'b 'c) 1))   ;; b
vector-set! (-> (Mut (Vec a)) Int a Void)primitive

Store into a slot (checked); returns void.

(define v (make-vector 3))
(vector-set! v 0 7)
(println v)   ;; #(7 0 0)
vector-length (-> (Vec a) Int)primitive

Number of slots in a vector.

(println (vector-length (vector 1 2 3)))   ;; 3
vector? (-> a Bool)primitive

Is this value a vector?

(println (vector? (vector 1)))   ;; #t
list->vector (-> (List a) (Mut (Vec a)))prelude

A fresh mutable vector holding the list's elements in order.

(println (list->vector (list 1 2 3)))   ;; #(1 2 3)
vector->list (-> (Vec a) (List a))prelude

A list of the vector's elements, in order.

(println (vector->list (vector 1 2 3)))   ;; (1 2 3)

Hashes

The default hash is immutable (a persistent HAMT: hash-set returns a NEW hash in O(log n)); make-hash is the tolerated mutable variant. Keys compare by identity (eq?).

hash (-> (Hash _ _))primitive

The empty immutable hash. (hash k v ...) builds one by chained hash-set.

(println (hash-count (hash 'a 1 'b 2)))   ;; 2
hash-set (-> (Hash k v) k v (Hash k v))primitive

A new immutable hash: like the input, with key mapped to value.

;; a NEW hash comes back; h0 is untouched
(define h0 (hash 'a 1))
(define h1 (hash-set h0 'b 2))
(println (hash-count h0))
(println (hash-count h1))
;; prints:
;;   1
;;   2
hash-remove (-> (Hash k v) k (Hash k v))primitive

A new immutable hash: like the input, without the key.

(println (hash-has-key? (hash-remove (hash 'a 1) 'a) 'a))   ;; #f
hash-ref (-> (Hash k v) k v)primitive

Look up a key (immutable or mutable hash); runtime error if absent.

(println (hash-ref (hash 'a 1) 'a))   ;; 1
hash-ref/default (-> (Hash k v) k v v)primitive

Look up a key; return the default if absent.

(println (hash-ref/default (hash) 'missing 0))   ;; 0
hash-has-key? (-> (Hash k v) k Bool)primitive

Is this key present?

(println (hash-has-key? (hash 'a 1) 'a))   ;; #t
hash-count (-> (Hash k v) Int)primitive

Number of keys present.

(println (hash-count (hash 'a 1 'b 2)))   ;; 2
hash-keys (-> (Hash k v) (List k))primitive

A list of the keys present (unspecified order).

(println (hash-keys (hash 'only 1)))   ;; (only)
hash? (-> a Bool)primitive

Is this value a hash (either flavor)?

(println (hash? (hash)))
(println (hash? (make-hash)))
;; prints:
;;   #t
;;   #t
make-hash (-> (Mut (Hash _ _)))primitive

Allocate an empty MUTABLE key/value map (eq?-keyed, open addressing).

(define m (make-hash))
(hash-set! m 'hits 1)
(println (hash-ref m 'hits))   ;; 1
hash-set! (-> (Mut (Hash k v)) k v Void)primitive

Map key to value (overwrites); returns void.

(define m (make-hash))
(hash-set! m 'k 1)
(hash-set! m 'k 2)
(println (hash-ref m 'k))   ;; 2
hash-remove! (-> (Mut (Hash k v)) k Void)primitive

Remove a key if present; returns void.

(define m (make-hash))
(hash-set! m 'k 1)
(hash-remove! m 'k)
(println (hash-has-key? m 'k))   ;; #f

Sets

Same story as hashes: immutable by default (set-add returns a new set), mutable on request (make-set), identity-keyed.

set (-> (Set _))primitive

The empty immutable set. (set v ...) builds one by chained set-add.

(println (set-count (set 1 2 2 3)))   ;; 3
set-add (-> (Set a) a (Set a))primitive

A new immutable set: like the input, with the value present.

;; a NEW set comes back; s0 is untouched
(define s0 (set))
(define s1 (set-add s0 'x))
(println (set-count s0))
(println (set-count s1))
;; prints:
;;   0
;;   1
set-remove (-> (Set a) a (Set a))primitive

A new immutable set: like the input, without the value.

(println (set-member? (set-remove (set 1 2) 1) 1))   ;; #f
set-member? (-> (Set a) a Bool)primitive

Is this value present?

(println (set-member? (set 1 2 3) 2))   ;; #t
set-count (-> (Set a) Int)primitive

Number of values present.

(println (set-count (set 'a 'b)))   ;; 2
set->list (-> (Set a) (List a))primitive

A list of the values present (unspecified order).

(println (set->list (set-add (set) 7)))   ;; (7)
list->set (-> _ _)prelude

An immutable set of the list's elements.

(println (set-count (list->set (list 1 2 2 3))))   ;; 3
set-union (-> _ _ _)prelude

An immutable set with every element of both sets.

(println (set-count (set-union (set 1 2) (set 2 3))))   ;; 3
set-subtract (-> _ _ _)prelude

An immutable set with a's elements that are not in b.

(println (set-member? (set-subtract (set 1 2) (set 2)) 2))   ;; #f
set-intersect (-> _ _ _)prelude

An immutable set with the elements common to both sets.

(println (set->list (set-intersect (set 1 2) (set 2 3))))   ;; (2)
set? (-> a Bool)primitive

Is this value a set (either flavor)?

(println (set? (set)))
(println (set? (list 1 2)))
;; prints:
;;   #t
;;   #f
make-set (-> (Mut (Set _)))primitive

Allocate an empty MUTABLE set (eq?-keyed, open addressing).

(define s (make-set))
(set-add! s 'x)
(println (set-count s))   ;; 1
set-add! (-> (Mut (Set a)) a Void)primitive

Add a value; returns void.

(define s (make-set))
(set-add! s 'x)
(set-add! s 'x)
(println (set-count s))   ;; 1
set-remove! (-> (Mut (Set a)) a Void)primitive

Remove a value if present; returns void.

(define s (make-set))
(set-add! s 7)
(set-remove! s 7)
(println (set-member? s 7))   ;; #f

Strings & symbols

Strings are immutable byte strings (ASCII-friendly); symbols are interned, so eq? compares them in O(1).

string? (-> a Bool)primitive

Is this value a string?

(println (string? "abc"))   ;; #t
string-length (-> Str Int)primitive

Number of bytes in a string.

(println (string-length "puffin"))   ;; 6
string-append (-> Str Str Str)primitive

Concatenate two strings.

(println (string-append "puf" "fin"))   ;; puffin
string-concat (-> (List Str) Str)primitive

Concatenate a list of strings in one allocation (linear; string-join's backbone).

(println (string-concat (list "a" "b" "c")))   ;; abc
string-join (-> (List Str) Str Str)prelude

Concatenate a list of strings with sep between elements (linear).

(println (string-join (list "a" "b" "c") ", "))   ;; a, b, c
substring (-> Str Int Int Str)primitive

Bytes [i, j) of a string (checked).

(println (substring "puffin" 0 3))   ;; puf
string=? (-> Str Str Bool)primitive

Are two strings byte-equal?

(println (string=? "abc" "abc"))   ;; #t
string<? (-> Str Str Bool)primitive

Lexicographic byte order on strings.

(println (string<? "apple" "banana"))   ;; #t
string-byte (-> Str Int Int)primitive

The byte at an index (checked; strings are byte strings, ASCII-friendly).

(println (string-byte "A" 0))   ;; 65
number->string (-> Int Str)primitive

Decimal rendering of an integer.

(println (string-append "n = " (number->string 42)))   ;; n = 42
string->number (-> Str _)primitive

The integer a string spells, or #f.

(println (string->number "42"))
(println (string->number "nope"))
;; prints:
;;   42
;;   #f
format (->* (Str) _ Str)prelude

Build a string from a template: ~a inserts a value, ~% a newline, ~~ a tilde.

(println (format "~a + ~a = ~a" 1 2 3))   ;; 1 + 2 = 3
value->string (-> a Str)primitive

Render any value exactly as display would, into a string.

(println (string-length (value->string (list 1 2 3))))   ;; 7
symbol? (-> a Bool)primitive

Is this value a symbol?

(println (symbol? 'abc))   ;; #t
symbol->string (-> Sym Str)primitive

The name of a symbol, as a fresh string.

(println (string-length (symbol->string 'hello)))   ;; 5
string->symbol (-> Str Sym)primitive

Intern a string as a symbol.

(println (eq? (string->symbol "cat") 'cat))   ;; #t
symbol<? (-> _ _ _)prelude

Lexicographic order on symbol names.

(println (symbol<? 'apple 'banana))   ;; #t

ADTs & matching

define-type declares an algebraic datatype whose constructors work in expressions and in match patterns; see the tutorial for the full story. Constructor instances are their own heap kind, disjoint from vectors.

adt? (-> a Bool)primitive

Is this value a define-type constructor instance?

(define-type Opt (None) (Some Int))
(println (Some 1))
(println (adt? (Some 1)))
(println (adt? (vector 1)))
;; prints:
;;   (Some 1)
;;   #t
;;   #f

I/O & the REPL

println renders any value the way the REPL does. (read) and (read-all) consume standard input (the playground's stdin box feeds them).

println (-> a Void)primitive

Display a value followed by a newline; returns void.

(println (list 1 'two "three"))   ;; (1 two three)
display (-> a Void)primitive

Display a value (no newline); returns void.

(display 'answer)
(display ": ")
(display 42)
(newline)
;; prints:
;;   answer: 42
displayln (-> _ _)prelude

Display a value followed by a newline (display, then newline).

(displayln "hi")   ;; hi
newline (-> Void)primitive

Print a newline; returns void.

(display 1)
(newline)
(display 2)
(newline)
;; prints:
;;   1
;;   2
read (-> Int)primitive

Read an integer from standard input.

;; with 3 4 on stdin
(println (+ (read) (read)))   ;; 7
read-all (-> Str)primitive

The rest of standard input, as one string.

;; with 1 2 3 on stdin
(println (string-length (read-all)))   ;; 5
eprintln (-> a Void)primitive

Display a value followed by a newline on standard error; returns void.

(eprintln 'warning)
;; on stderr: warning
read-file (-> Str Str)primitive

The named file's bytes, as a string (exits with an error if unreadable).

(write-file "note.txt" "hello")
(println (read-file "note.txt"))   ;; hello
write-file (-> Str Str Void)primitive

(Re)write the named file with the string's bytes.

(write-file "out.txt" "data")
(println (file-exists? "out.txt"))   ;; #t
file-exists? (-> Str Bool)primitive

Whether the named file exists and is readable.

(println (file-exists? "no-such-file.txt"))   ;; #f
command-line-args (-> (List Str))primitive

The program's command-line arguments (a list of strings, argv[0] excluded).

;; run with no arguments
(println (command-line-args))   ;; ()
system (-> Str Int)primitive

Run a shell command; its exit code.

(println (system "exit 3"))   ;; 3

Control & misc

Halting, fresh names, and the remaining predicates.

error (-> a _)primitive

Display error: <value> and halt the program.

(error 'boom)   ;; error: boom
gensym (-> Sym Sym)primitive

A fresh symbol whose name extends the given one.

;; a fresh name every call
(define t (gensym 'tmp))
(println (symbol? t))   ;; #t
procedure? (-> a Bool)primitive

Is this value a procedure (closure)?

(println (procedure? (lambda (x) x)))
(println (procedure? 'car))
;; prints:
;;   #t
;;   #f
void? (-> a Bool)primitive

Is this value void?

(println (void? (display "")))   ;; #t

Foreign functions

The foreign form imports typed C functions from a shared library (see the tutorial's FFI section); opaque C pointers cross as branded, unforgeable foreign handles.

foreign-ptr? (-> a Bool)primitive

Is this value a foreign handle (an opaque pointer from a foreign library)?

;; #t only for handles returned by foreign imports
(println (foreign-ptr? 5))
(println (foreign-ptr? "lib"))
;; prints:
;;   #f
;;   #f