Special Forms
Special forms are built into the evaluator — they control evaluation order and cannot be redefined.
Definitions & Assignment
define
Bind a value or define a function.
(define x 42) ; bind a value
(define (square x) (* x x)) ; define a function (shorthand)set!
Mutate an existing binding.
(set! x 99)Functions
lambda
Create an anonymous function.
(lambda (x y) (+ x y))fn
Alias for lambda.
(fn (x) (* x x))
(fn (x . rest) rest) ; rest parameters with dot notationConditionals
if
Two-branch conditional.
(if (> x 0) "positive" "non-positive")cond
Multi-branch conditional with else fallback.
(cond
((< x 0) "negative")
((= x 0) "zero")
(else "positive"))case
Match a value against literal alternatives.
(case (:status response)
((:ok) "success")
((:error :timeout) "failure")
(else "unknown"))when
Execute body only if condition is true. Returns nil otherwise.
(when (> x 0) (println "positive"))unless
Execute body only if condition is false.
(unless (> x 0) (println "not positive"))Bindings
let
Parallel bindings — all init expressions are evaluated before any binding is created.
(let ((x 10) (y 20))
(+ x y))let*
Sequential bindings — each binding is visible to subsequent ones.
(let* ((x 10) (y (* x 2)))
(+ x y))letrec
Recursive bindings — all bindings are visible to all init expressions. Useful for mutually recursive functions.
(letrec ((even? (fn (n) (if (= n 0) #t (odd? (- n 1)))))
(odd? (fn (n) (if (= n 0) #f (even? (- n 1))))))
(even? 10))Named let
Loop construct with tail-call optimization.
(let loop ((i 0) (sum 0))
(if (= i 100)
sum
(loop (+ i 1) (+ sum i))))Sequencing & Logic
begin
Evaluate expressions in order, return the last result.
(begin expr1 expr2 ... exprN)and
Short-circuit logical AND. Returns the last truthy value or #f.
(and a b c)or
Short-circuit logical OR. Returns the first truthy value or #f.
(or a b c)Iteration
do
Scheme do loop with variable bindings, step expressions, and a termination test.
;; (do ((var init step) ...) (test result ...) body ...)
(do ((i 0 (+ i 1))
(sum 0 (+ sum i)))
((= i 10) sum)) ; => 45With a body for side effects:
(do ((i 0 (+ i 1)))
((= i 5))
(println i)) ; prints 0..4Lazy Evaluation
delay
Create a promise — the expression is not evaluated until forced.
(define p (delay (+ 1 2)))force
Evaluate a promise and memoize the result. Non-promise values pass through.
(force p) ; => 3 (evaluate and memoize)
(force p) ; => 3 (returns cached value)
(force 42) ; => 42 (non-promise passes through)promise?
Check if a value is a promise.
(promise? p) ; => #tpromise-forced?
Check if a promise has already been forced.
(promise-forced? p) ; => #t (after forcing)Record Types
define-record-type
Define a record type with constructor, predicate, and field accessors.
(define-record-type point
(make-point x y)
point?
(x point-x)
(y point-y))
(define p (make-point 3 4))
(point? p) ; => #t
(point-x p) ; => 3
(point-y p) ; => 4
(record? p) ; => #t
(type p) ; => :point
(equal? (make-point 1 2) (make-point 1 2)) ; => #tError Handling
try / catch
Catch errors with structured error maps.
(try
(/ 1 0)
(catch e
(println (format "Error: ~a" (:message e)))
(:type e))) ; => :evalError maps in catch have keys: :type, :message, :stack-trace, and variant-specific keys (:value, :expected/:got, :name).
throw
Throw any value as an error.
(throw "something went wrong")
(throw {:code 404 :reason "not found"})