Special Forms
Core syntax constructs for definitions and control flow.
Definitions
define
Define a variable or procedure.
;; Variable definition
(define pi 3.14159)
(define message "hello")
;; Procedure definition (shorthand)
(define (square x)
(* x x))
;; Equivalent to:
(define square
(lambda (x) (* x x)))
;; Multiple expressions in body
(define (greet name)
(display "Hello, ")
(display name)
(newline))lambda
Create an anonymous procedure.
(lambda (x) (* x x)) ; one parameter
(lambda (x y) (+ x y)) ; two parameters
(lambda args (length args)) ; rest parameter (collects all args)
(lambda (x . rest) x) ; one required, rest optionalset!
Mutate an existing binding.
(define counter 0)
(set! counter (+ counter 1))Use sparingly. Prefer functional style when possible.
Local Bindings
let
Bind variables in parallel (bindings can't reference each other).
(let ((x 1)
(y 2))
(+ x y))
; => 3
;; Named let for recursion
(let loop ((n 5) (acc 1))
(if (zero? n)
acc
(loop (- n 1) (* acc n))))
; => 120 (factorial)let*
Bind variables sequentially (each can see previous bindings).
(let* ((x 1)
(y (+ x 1))
(z (+ y 1)))
(list x y z))
; => (1 2 3)letrec
Bind variables that can reference each other (for mutual recursion).
(letrec ((even? (lambda (n)
(or (zero? n) (odd? (- n 1)))))
(odd? (lambda (n)
(and (not (zero? n)) (even? (- n 1))))))
(even? 10))
; => #tConditionals
if
Two-branch conditional.
(if (> x 0)
"positive"
"not positive")
;; Without else branch (returns unspecified value if false)
(if (file-exists? path)
(load-file path))cond
Multi-branch conditional with pattern-like clauses.
(cond
((< x 0) "negative")
((= x 0) "zero")
(else "positive"))
;; With => to pass test result to procedure
(cond
((assoc key alist) => cdr)
(else default))case
Dispatch on value using eq? comparison. Best for symbols and small integers.
(case color
((red green blue) "primary")
((cyan magenta yellow) "secondary")
(else "other"))when / unless
Single-branch conditionals for side effects.
(when (> x 0)
(display "positive")
(newline))
(unless (null? items)
(process-items items))Boolean Operations
and
Short-circuit AND. Returns last true value or first false.
(and #t #t) ; => #t
(and 1 2 3) ; => 3
(and #f (error)) ; => #f (error not evaluated)or
Short-circuit OR. Returns first true value or last false.
(or #f #f) ; => #f
(or #f 1 2) ; => 1
(or (find x) default) ; common patternnot
Boolean negation.
(not #f) ; => #t
(not #t) ; => #f
(not '()) ; => #f (only #f is false)Sequencing
begin
Execute expressions in order, return last value.
(begin
(display "one")
(display "two")
"result")
; prints: onetwo
; => "result"Iteration
For iteration, use named let or higher-order functions like map and fold.
Named let
;; Count down
(let loop ((n 5))
(when (> n 0)
(display n)
(loop (- n 1))))
; prints: 54321
;; Accumulating loop
(let loop ((items '(1 2 3 4 5))
(sum 0))
(if (null? items)
sum
(loop (cdr items) (+ sum (car items)))))
; => 15Higher-order functions
;; Transform each element
(map (lambda (x) (* x 2)) '(1 2 3)) ; => (2 4 6)
;; Keep matching elements
(filter even? '(1 2 3 4 5)) ; => (2 4)
;; Reduce to single value
(fold-left + 0 '(1 2 3 4 5)) ; => 15