Scheme Cheat Sheet
Foundational Scheme syntax including define, let forms, list operations, and recursion for this minimalist Lisp dialect.
Basic Syntax & Definitions
Defining values, functions, and conditionals.
(define x 10)(define (square x) (* x x))(define square (lambda (x) (* x x))) ; equivalent form(if (> x 0) 'positive 'negative)(cond ((> x 0) 'positive) ((< x 0) 'negative) (else 'zero))
Let Forms
Local bindings with let, let*, and named let.
(let ((a 1) (b 2)) (+ a b)) ; bindings evaluated in parallel(let* ((a 1) (b (+ a 1))) (+ a b)) ; sequential, b can see a(let loop ((i 1) (acc 0)) ; named let for iteration (if (> i 5) acc (loop (+ i 1) (+ acc i))))
List Operations
Core procedures for working with pairs and lists.
- (car lst)- returns the first element of a pair/list
- (cdr lst)- returns the rest of the list after the first element
- (cons a b)- constructs a new pair with a as car and b as cdr
- (list a b c)- builds a proper list from its arguments
- (null? lst)- true if lst is the empty list '()
- (length lst)- returns the number of elements in a proper list
- (append lst1 lst2)- concatenates two lists into one
- (map proc lst)- applies proc to each element, returns a new list
Recursion
Scheme relies on recursion instead of traditional loops.
(define (factorial n) (if (= n 0) 1 (* n (factorial (- n 1)))))(factorial 5) ; => 120(define (sum-to n) (let loop ((i 1) (acc 0)) (if (> i n) acc (loop (+ i 1) (+ acc i)))))(sum-to 100) ; => 5050, tail-recursive so it runs in constant space
Higher-Order Functions
map, filter, and fold over lists with lambdas.
(map (lambda (x) (* x x)) '(1 2 3)) ; => (1 4 9)(filter odd? '(1 2 3 4 5)) ; => (1 3 5)(fold-left + 0 '(1 2 3 4)) ; => 10 (SRFI-1)(fold-right cons '() '(1 2 3)) ; => (1 2 3)(apply max '(3 1 4 1 5)) ; => 5(for-each display '(a b c))
Tail Recursion & named let
Iteration via proper tail calls using a named let accumulator.
(define (factorial n) (let loop ((i n) (acc 1)) (if (= i 0) acc (loop (- i 1) (* acc i))))) ; tail call, no stack growth(factorial 5) ; => 120; do-loop equivalent(do ((i 0 (+ i 1)) (s 0 (+ s i))) ((= i 5) s)) ; => 10
Predicates & Equality
Type tests and the three equality procedures.
- eq?- pointer identity; reliable for symbols and small ints only
- eqv?- like eq? but also correct for numbers and characters
- equal?- deep structural equality for lists, strings, vectors
- null? / pair? / list?- test empty list, cons cell, proper list
- number? / string? / symbol?- type predicates for core data types
- zero? / positive? / even?- numeric predicates
- procedure?- true if the value is callable
Multiple Values & call/cc
Returning several values and capturing continuations.
(define (divmod a b) (values (quotient a b) (remainder a b)))(call-with-values (lambda () (divmod 17 5)) (lambda (q r) (list q r))) ; => (3 2); escape from a loop with a continuation(call/cc (lambda (return) (for-each (lambda (x) (if (negative? x) (return x))) '(1 2 -3 4))))
Write recursive functions in tail-call form (like the named-let loop above) — conforming Scheme implementations guarantee proper tail-call optimization, so tail recursion runs in constant stack space just like a loop.