Derived forms are built into the normalizer, not user macros: cond, case, and, or, when, unless, let*, named let, do, quasiquote, and guard.
At a glance
LISPEX
(let* ((x 6) (y (+ x 1))) (* x y))Result
OUTPUT
42Current guarantees
- Expansion uses fresh identities and hidden intrinsics, preserving hygiene under user shadowing.
- Normalization preserves defined tail positions and source diagnostics.
guardis a fixed core-facing construct for catchable faults, not a general macro facility.
Normalization surface
| Surface form | Core strategy | Pinned boundary |
|---|---|---|
| cond / case | nested if with fresh temporaries; case uses hidden eqv? | tail clause preserved; no cond => |
| and / or | short-circuit nested if | single final operand remains tail |
| when / unless | if plus begin or zero-value values | false path returns zero values |
| named let / do | hygienic letrec loop | recursive application is tail |
| quasiquote | quote plus hidden constructors | bare unquote outside quasiquote is static E1xx |
Boundaries
define-syntax, syntax objects, and arbitrary expansion are rejected.