Error Handling: Preparing for the Unexpected

Not all thoughts flow along the right path. In Lispex, an error is not a failure, but another form of data. Learn to handle unexpected situations gracefully and ensure the stability of your programs.

Lispex v1 defines an input‑only S‑expression surface and deterministic normalization. This page covers the diagnostics you can expect at parse/normalize time. Runtime behavior and exceptions are backend‑specific and out of scope here.

Diagnostic codes

Lispex v1 emitters should use consistent codes (recommended):

  • E100 — Syntax: illegal token, paren/dotted list error
  • E110 — Reserved: attempt to bind a reserved keyword
  • E120 — Macro: forbidden user macro/reader extension
  • E130 — Derived: malformed derived form (e.g., empty cond)
  • E140 — Syntax: illegal dotted list form (e.g., extra terms after dot)
  • E150 — String: invalid or out‑of‑range escape (e.g., malformed \x..;)
  • W200 — Static: unused binding
  • W210 — Static: possible immediate self‑reference in letrec
  • W310 — Compat: #u8 replaced under R5RS‑compat
  • W320 — Compat: case compare semantics note
  • W330 — Style: % alias used; prefer modulo

Message format (recommended): CODE file:line:col message

Examples

E110: reserved keyword binding

(let ((if 1)) if)   ; E110: cannot bind reserved word: if

E120: forbidden macro/reader forms

(define-syntax swap ...)    ; E120: user macros are not allowed in v1
#; (this is a reader extension)   ; E120

E130: malformed derived forms

(cond)                       ; E130: empty cond
(and 1 . 2)                  ; E100/E130 depending on reader

E100: dotted list syntax

(a b . c d)                  ; E100: illegal dotted list

E140: illegal dotted list form

(a .)                         ; E140: missing tail after dot

W310/W320: R5RS‑compat notes

With ;! compat: r5rs enabled:

  • #u8(...) may be replaced by a plain vector with a warning (W310).
  • case is described here using equal? for simplicity; R5RS evaluators compare via eqv? (W320).

W330: modulo alias warning

Using % instead of modulo may emit a style warning:

(% 10 3)    ; W330: prefer (modulo 10 3)

Best practices

  • Stick to Core forms + allowed derived forms; avoid user macro constructs.
  • Prefer let* when sequential dependencies matter; use letrec for local recursion.
  • Keep module headers simple (module ...) if used; expect flattening under R5RS‑compat.
  • Add small golden tests around normalization to catch E130 early.