Basic Syntax Forms

Look up the syntax, evaluation order, results, and errors of core forms.

See it run

LISPEX
((lambda (x) (if #t x 0)) 42)

Observed result

OUTPUT
42

lambda creates a procedure with parameter x. The call binds x to 42. if tests #t and evaluates only x, so the result is 42. It skips the other branch, 0.

Run the examples in the playground. Each returns 42.

Read the core forms

A form is a piece of program syntax. Core forms are the forms Lispex evaluates directly. They include quotation, variable reference, if, sequencing, lambda, calls, assignment, definition, lexical binding, and control forms.

  • if requires a test and both branches. begin and procedure bodies run from left to right.
  • lambda accepts a fixed parameter list or a dotted list for extra arguments.
  • set! changes an existing cell, the storage location associated with a name. define creates or updates a top-level cell.
  • quote returns immutable data without evaluating its elements. For example, '(+ 1 2) returns the list (+ 1 2).

A datum is one item of data, such as a number, symbol, or list. The quote row below uses this term.

Define a module at top level

LISPEX
(module doubling
  (export twice)
  (define (twice x) (* x 2)))

(twice 21)

Observed result

OUTPUT
42

The call (twice 21) works outside the module because its body becomes part of the surrounding top level. The definitions share that scope. The module name does not create a separate namespace.

Write a module as (module name (export id ...) (import name ...) body ...). Its optional export and import clauses precede the body. Lispex checks these headers, discards them, and places the body forms at top level. Nesting module inside another form raises E130.

Syntax, evaluation, and results

FormArguments / evaluationResult or fault
quoteone datum; elements are not evaluatedimmutable datum
iftest, true branch, false branch; evaluates the test firstvalues from the selected branch; E320 if the test does not produce exactly one value
lambdaparameters and one or more body formsclosure; E302 when called with the wrong number of arguments
set!a name and an expression producing one valuezero values; E303 if the name is unbound
let / letrecbinding list and one or more body formsvalues from the last body form; E321 when reading an uninitialized letrec binding
modulename, zero to two header clauses, one or more body formsbody forms placed at top level; E130 elsewhere

A closure is a procedure that keeps access to the bindings where it was created. See Procedures for parameters and Bindings for cells and scope. With lexical binding, program structure determines where a name is looked up.

Keep going

Lispex converts shorthand into core forms before execution. This step is called normalization. Syntax That Expands into Basic Forms describes those conversions. Expressions and Evaluation Order explains when each part runs.