This is a rough outline of a Lisp system, it must be read from bottom to top to emphasize bottom-up approach to programming as an opposite to popular but broken top-down.
Each layer of special forms and procedures (which in some cases define a DSL) act as a basic building blocs for the layer above it. At the higher-levels everything is mixed (messed?) up.
Hierarchy of Special Forms and Primitive Procedures (layers of DSLs):
- CLOS DSL (macros, procedures):
define-class define-method, etc.
- Structures DSL (macros, procedures):
Having a Lisp system we could use meta-programming to extend it with so-called "high-level" features, such as Object System.
- Looping forms DSLs (macros):
do loop for, etc.
- High-order list procedures:
filter map for-each foldr foldl, etc.
- Logic procedures:
and or not
With constrol structures, macros and environment we could define generic high-order procedures for aggregates, etc.
- Environment (special forms):
- Control structures (special forms):
begin let cond
- Macro DSL (special forms):
quasi-quote unquote unquote-splicing
Since we have Lists (which are nested Pairs) we could define an environment (which is a, logically a set of nested associative lists) and additional control structures.
- List DSL (procedures):
'() null? list append, etc.
- Pair DSL (procedures):
cons car cdr pair?
- Fundamental Special Forms:
lambda #t #f if quote
- Special form is a Lisp expression (parenthesized list notation) which has its own evaluation rule, explicitly embedded into the 'eval procedure.
- Special forms are evaluated at run-time as special cases within the
- Special forms might be syntactically different from the standard procedure application form - a procedure (car) followed by a parameter list (cdr) in parenthesis.
lambdais the most fundamental special form, it creates a new procedure.
ifis a special form which evaluates only one of its "branch" expression, depending on the result of evaluation of given "test" expression.
quoteis a special form which allows a Lisp expression to be a part of another Lisp expression, without being evaluated.
- Macros are special forms which are expanded (evaluated) by the
readprocedure, when it reads expressions from its standard input and transforms them into actual Lisp forms (lists).
- Macros perform syntactic transformations of Lisp forms (lists), keeping its semantics constant.
- Macros are
lambdaexpressions which are annotated with the 'macro type-tag. Their domain and range are syntactically correct Lisp forms.
- simplify! generalize!
- all you need is lambda (if and quote)
- everything is a symbol (pointer)
- everything is made out of conses (except for special cases)
- code is data!
- there are no vars, just values (bound to symbols)
- there are no objects, just values
- values, not variables, has types attached to them as tags.
- type-tags, keywords are just symbols
- macros are just lambdas tagged (annotated) with the 'macro tag (to be evaluated (expanded) by
- quoting expressions are special forms, whose domain is Lisp forms (Lists)
- quoting is a way to turn off evaluation a Lisp form inside of another form
- unquoting is a way to evaluate only selected parts of nested forms
- Lisp is a meta-language for itself
- Lisp is just layers of DSLs embedded in Lisp (recursive definition)
- high-order procedures are the way to implement primitive DSLs
- macros are the way to define new control structures for advanced DSLs
- cons car cdr pair? is the most fundamental, primitive DSL
- wishful thinking is the way to designing good DSLs
Let's talk about the IF special form.