sigildocs

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 optional

set!

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))
; => #t

Conditionals

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 pattern

not

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)))))
; => 15

Higher-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