Tue Jun 2 13:17:13 CEST 2009
Why use (Scheme) macros?
Essentially this, but put a bit differently.
Macros escape the default semantics of plain Scheme:
- names produce values by variable reference
- parentheses produce values by passing values to abstract
The exceptions to this standard behaviour are expressed using the
primitive forms LAMBDA and QUOTE.
The LAMBDA form is used for two things: to _introduce_ variables in a
body of code (create code with holes in it) and _abstract_ code as a
value that can be stored in a variable. This value is a computation
that takes inputs it received upon application, puts them in the
holes, and evaluates the resulting expression producing a result
The QUOTE form changes the meaning of parenthesis and names entirely,
and instantiates them as a data structure.
In essence, all other macros compose these two forms or abstractions
built on top of them. One could distinguish different classes based
on distinct intentions:
(A) Abstraction: the only way to build a construct out of macros is to
build it as a macro.
(B) Binding: Introducting names in code bodies using LAMBDA. New
binding forms facilitate the introduction of local names for
domain-specific data structures. (i.e. data structure pattern
(C) Code abstraction: strict evaluation (run-it-now) can only be
escaped by wrapping code in a LAMBDA form. Sometimes it makes
sense to build abstractions that modify _when_ code executes, by
keeping possible future behaviour stored in a variable.
(i.e. lazy evaluation).
(D) Data abstraction: analogous to Code abstraction, it is possible to
create data structures using the QUOTE form. (i.e. QUASIQUOTE).
Note that this classification excludes macros for partial evaluation =
compile-time code specialization. However, Scheme is not well
equipped for this kind of use: functions abstracted by macros can no
longer be used as function values for higher-order programming.