Preview
Sign inSign up
Forms and builtinsSpecial forms

Forms and builtins

Special forms

Syntax built into the evaluator. Their names are reserved and can't be redefined.

(define name value)
(define (name param ... [. rest]) body ...)

Defines a variable or a procedure. At the top level it defines a global; inside a body it scopes over the rest of that body.

(define (square x) (* x x))
(square 12)

=>144

(lambda (param ...) body ...)
(lambda (param ... . rest) body ...)
(lambda args body ...)

Creates a procedure. A dotted last parameter, or a single symbol, collects the extra arguments as a list.

((lambda (a . more) (list a more)) 1 2 3)

=>(1 (2 3))

(if test consequent [alternative])

Evaluates consequent if test is anything but #f, otherwise alternative.

(if (> 3 2) 'yes 'no)

=>yes

(cond (test body ...) ... [(else body ...)])

Evaluates the body of the first clause whose test isn't #f. A clause with only a test returns the test's value.

(define (sign n) (cond ((< n 0) 'negative) ((= n 0) 'zero) (else 'positive)))
(map sign '(-5 0 5))

=>(negative zero positive)

(and expr ...)

Evaluates left to right and stops at the first #f. Returns the last value, or #t with no arguments.

(and 1 2 3)

=>3

(or expr ...)

Evaluates left to right and returns the first value that isn't #f, or #f.

(or #f '() 3)

=>()

(when test body ...)

Evaluates the body if test isn't #f.

(when (> 3 2) (display "bigger") 'done)

stdoutbigger

=>done

(unless test body ...)

Evaluates the body if test is #f.

(unless (> 1 2) 'smaller)

=>smaller

(let ((name value) ...) body ...)
(let loop ((name value) ...) body ...)

Binds names to values for the body. The values are evaluated before any name is bound. Named let defines a procedure loop you can call to iterate; calls in tail position don't grow the stack.

(let loop ((i 0) (acc '()))
  (if (= i 5) (reverse acc) (loop (+ i 1) (cons (* i i) acc))))

=>(0 1 4 9 16)

(let* ((name value) ...) body ...)

Like let, but each value can use the names bound before it.

(let* ((x 2) (y (* x 10))) (+ x y))

=>22

(letrec ((name value) ...) body ...)

Like let, but the values can refer to all the names, so procedures can call each other. letrec* is the same.

(letrec ((ev? (lambda (n) (if (= n 0) #t (od? (- n 1)))))
         (od? (lambda (n) (if (= n 0) #f (ev? (- n 1))))))
  (ev? 10))

=>#t

(begin expr ...)

Evaluates the expressions in order and returns the last value. At the top level, definitions inside it are global.

(begin (display "a") (display "b") 'c)

stdoutab

=>c

(set! name value)

Assigns a new value to an existing variable.

(define (make-counter)
  (let ((n 0)) (lambda () (set! n (+ n 1)) n)))
(define c (make-counter))
(c) (c) (c)

=>3

(quote datum)
'datum

Returns the datum without evaluating it.

'(1 (2 three) "four")

=>(1 (2 three) "four")

esc