http://t3x.org/mcl/mcl.txt.html   (light|dark)


The   M I C R O  C O M M O N  L I S P   Manual

By Nils M Holm, 2019, 2020, 2025


0 Quick Summary

For the impatient LISP user:

MICRO COMMON LISP is a purely symbolic subset of
Common LISP. Its only data types are the atom
(symbol), the cons/list, and the function. It
provides tail call elimination, macros, image
files, quasiquotation, and command line editing.
There are different namespaces for variables and
functions/macros.

The following special forms exist:

Core:    FSETQ FUNCTION IF IFNOT LAMBDA PROGN
         QUOTE SETQ

Derived: AND COND DEFMACRO DEFPARAMETER DEFUN DO
         LABELS LET LET* OR QUASIQUOTE

The following functions are predefined:

Built-in: APPLY ATOM CAR CDR CONS EQ EOFP ERROR
          FUNCALL GC GENSYM LOAD MACRO-FUNCTION
          PRINC READ RPLACA RPLACD SUSPEND
          SYMBOLS TERPRI

Derived:  APPEND ASSOC CAAR ... CDDDR EQUAL LIST
          MACROEXPAND-1 MAPCAR MAPLIST MEMBER
          NCONC NOT NRECONC NREVERSE NULL PRINT
          REMOVE-IF-NOT REVAPPEND REVERSE

The following syntactic sugar exists:

  'x  is  (QUOTE x)
  `x  is  (QUASIQUOTE x)
  ,x  is  (UNQUOTE x)
 ,@x  is  (UNQUOTE-SPLICE x)
 #'x  is  (FUNCTION x)
   %  is  the EOT


1 S-Expressions

A Symbol is any combination of these characters:

A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 0 - * &

Other characters can be included by slashifying
them (prefixing them with a \).

Lower case characters in symbols will be
converted to upper case, unless slashified.

A Pseudo-String is a self-quoting symbol that
contains the literal characters between two
double quote (") characters. Formally, the
pseudo-string "Foo" is equal to (QUOTE F\o\o).

An Atom is everything that is not a pair or list.
In MICRO COMMON LISP this is the basically the
symbol, but functions are also atomic.

An S-Expression is either an atom or a pair.

A Cons (or Pair) is an ordered pair of two
S-expressions:

(CAR-PART . CDR-PART)

A pair may contain other pairs:

((A . B) . C)
(A . (B . C))
((A . B) . (C . D))

A nested pair of the form

(A . (B . C))   may be written as   (A B . C)

and

(A . NIL)       may be written as   (A)

The rules apply inductively, so

(A . (B . (C . NIL)))  =  (A B C)


1.1 Lists

A List is an S-expression that is either NIL or a
pair whose cdr part is a list:

List  =  NIL  or  (S-expression . List)

These are Lists:

()
NIL
(FOO)
(FOO BAR BAZ)
(FOO (A . B) (NESTED LIST))

The notations () and NIL both indicate the empty
list.

A list whose rightmost cdr part is a symbol is
called a Dotted List. These are dotted lists:

(A B . C)
((FOO BAR) . BAZ)

The pair is a two-element dotted list.

An Association List (or Alist) is a list of pairs
(associations), where the car part of each
association is called the Key and the cdr part
the Value of the association:

((<key1> . <value1>) ... (<keyN> . <valueN>))

See ASSOC for details.


1.2 Comments

A Comment may be included anywhere (even inside
of a form, but not inside of an atom) by
inserting a semicolon (;). Comments extend to the
end of the current line.

Example:

(SETQ FOO  ; this is a comment
  (QUOTE BAR))


1.3 Unreadable Forms

A form that contains characters other than those
listed in the previous sections are unreadable,
i.e. they cannot be read by the LISP reader.

Unreadable forms are sometimes output by the
system to represent data that have no unambiguous
textual representation, like <EOT> or <FUNCTION>.


2 Expressions

An Expression is an S-expression with a meaning.

x => y     denotes that x evaluates to y;
           y is the Value of x.

undefined  denotes an undefined value.

There are four kinds of expressions:

Variables
Lambda Abstraction
Function Application
Special Forms

Strictly speaking, lambda abstraction is
also a special form, but it will be discussed
separately.


2.1 Variables and Function Names

Each symbol can be bound to two Boxes called its
Value Box and its Function Box. The two bindings
are independent, i.e. the same symbol can be
bound to two different values at the same time.

A Box is a container that contains a value.

The Variable Binding of a function is retrieved
from a value box by refering to the symbol
outside of any lists or in a Value position of
a function call:

Value
(Function Value Value ...)

The Function Binding of a symbol is retrieved by
refering to the symbol in the Function position
of a function call or by using the FUNCTION
special operator.

References to symbols with no corresponding
binding are undefined:

 unbound-symbol   =>  undefined
(unbound-symbol)  =>  undefined

The term "the variable V is bound to the value X"
is short for "the variable V is bound to a box
containing the value X".

A Constant is a variable that is bound to its own
name:

constant  =>  constant

For instance, the canonical "true" value, T, is a
constant:

T  =>  T

Variable bindings are created by the SETQ special
form, by lambda abstraction, and by LET and
related special forms.

Function bindings are created by the special
forms FSETQ, DEFUN, DEFMACRO, and LABELS.


2.2 Lambda Abstraction

(Lambda <vars> <body>)

is a Lambda Abstraction. Its value is a Function.

Names enclosed in angle brackets are Meta-
Syntactic Variables. They are not part of LISP,
but describe parts of special forms. They may
represent single expressions or sequences of
expressions.

<Vars> is a list of variables of a function and
<body> is the Body of a function.

<Vars> is a list of symbols. It may be empty and
it may contain the keyword &REST.

<Body> must consist of at least one expression.

Examples: (lambda (x) x)
          (lambda (f x) (print 'f) (f x))
          (lambda () (print 'hello\ world))
          (lambda (x &rest y) y)

The variables of a function are created by
binding their symbols to boxes containing the
arguments of the function. This happens when the
function is being applied to some arguments.

The forms (LAMBDA <vars> <body>) and
(FUNCTION (LAMBDA <vars> <body>)) are equal.


2.3 Function Application

A variable X is Bound in an expression E, if

- E is a lambda function
AND
- X is a variable of E

Examples:

X   is     bound in  (lambda (x) (f x))
F   is not bound in  (lambda (x) (f x))
Neither is bound in  (f x)

When a variable X is not bound in an expression E,
X is Free in E; X is a free variable of E.

A function is Called or Applied to Arguments
using the syntax

(function argument ...)

The following steps are involved in the
application:

(1) each argument in the application is
    evaluated
(2) the function is retrieved from the function
    symbol
(3) a box is created for each variable of the
    function
(4) the value of each argument is stored in the
    corresponding box
(5) thereby every FREE argument variable in the
    body of the function is bound to a value
(6) the body of the function is evaluated
(7) the value of the body is returned

Variables are associated with arguments by
position, i.e. the first argument is stored in
the first variable, etc.

For instance:

((lambda (x y) (cons x y)) (quote a) (quote b))

; evaluate arguments:
; (quote a) => A,  (quote b) => B
((lambda (x y) (cons x y)) A B)

; create variables and store A in X and B in Y,
; giving the body
(cons A B)

; evaluate the body, giving the value
(A . B)

The function part in the function call

(function value ...)

can be a symbol that is bound to a function via
its function box or a lambda function. E.g.:

((lambda (x) (cons x x)) 'foo)


2.5 Higher Order Functions

A Higher-Order function is a function that either
takes a function as an argument or returns a
function (or both). Because functions are bound
in a different namespace than variables, the
FUNCALL function is needed to call a function
that is bound in a value box:

(defun complement (p)
  (lambda (x) (not (FUNCALL p x))))

This function takes a predicate P as its argument
and returns another predicate that implements the
complement of the original predicate, i.e. it
will return NIL where P returns T and vice versa.

The FUNCTION special operator is needed to
retrieve a function from its function box and
pass it to another function:

(complement (FUNCTION null))

To call the function returned by a higher-order
function, FUNCALL has to be used:

(funcall (complement #'null) 'foo)  =>  T

#'F is short for (FUNCTION F).


2.5 Lexical Scope

All free variables of a function indefinitely
retain the values they had when the function was
created (unless their values are changed using
SETQ or FSETQ).

For example:

(defun conser (x)
  (lambda (y)
    (cons x y)))

defines a function CONSER that, when applied to
an argument X, will return another function that
will cons X to its argument Y. E.g., the
function returned by

(CONSER 'FOO)

will cons FOO to its argument.

Changing the value of X after creating the
function will not change the behavior of the
function, because the function retains the value
X had when it was created. The function is said
to "close over" the variable X. For example:

(setq cons-foo (conser 'foo))  =>  <FUNCTION>
(setq cons-bar (conser 'bar))  =>  <FUNCTION>
(setq x 'something-else)       =>  SOMETHING-ELSE

(funcall cons-foo 'baz)        =>  (FOO . BAZ)
(funcall cons-bar 'baz)        =>  (BAR . BAZ)

All variables in MICRO COMMON LISP have lexical
scope, as outlined in this section. Therefore:

(let ((x 'lexical))
  (let ((f (lambda () x)))
    (let ((x 'dynamic))
      (funcall f))))        =>  LEXICAL


2.6 Optional Arguments

Given an ordinary argument list there has to be
exactly one argument per variable:

((lambda (x) x))         =>  undefined
((lambda (x) x) 'a)      =>  A
((lambda (x) x) 'a 'b))  =>  undefined

When the argument list of a function contains the
keyword &REST, the variables before the keyword
bind like fixed arguments, above, and the single
variable after the keyword (the &REST variable)
binds to a list containing any excess arguments
that may be passed to the function:

((lambda (x &rest y) y))            =>  undefined
((lambda (x &rest y) y) 'a)         =>  NIL
((lambda (x &rest y) y) 'a 'b))     =>  (B)
((lambda (x &rest y) y) 'a 'b 'c))  =>  (B C)

When there are no fixed arguments, the &REST variable binds to a list of all arguments:

((lambda (&rest x) x)) => NIL ((lambda (&rest x) x) 'a) => (A) ((lambda (&rest x) x) 'a 'b)) => (A B)

3 Special Forms

A Special Form is an expression of the form

(<keyword> <argument> ...)

The syntax is the same as in function application, but there are some differences: When a syntactic Keyword is found in the first slot of a list, neither the keyword nor any <argument>s will be evaluated. The <argument>s will then be processed by the LISP system according to the semantics of the corresponding special form. The semantics may or may not involve the evaluation of some of the <argument>s.

A keyword is sometimes also called a Special Operator. The special operators of the MICRO COMMON LISP language are

FSETQ FUNCTION IF IFNOT LAMBDA PROGN QUOTE SETQ

3.1 (FSETQ <var> <form>) => FUN (FSETQ <var> <form> T) => FUN --------------------------------------------------------- Evaluate the given <form> (usually a lambda expression or a macro) and store its value in the function box bound to the variable <var>. Return <var>. When <var> is not bound to any function box, a fresh box will be created and <var> will be bound to it.

In standard Common LISP FSETQ can be defined as:

(defmacro fsetq (x fn ignore) `(setf (symbol-function ',x) ,fn))

Note that FSETQ will modify function bindings of local variables unless a third argument is given. The third argument will be ignored, but when present, FSETQ will always modify the global binding of <var>. This is the behavior emulated in the above Common LISP definition.

Example: (fsetq foo (lambda (x) x)) => <FUNCTION> (foo 'bar) => BAR

3.2 (FUNCTION <form>) => FUN

If <form> is a lambda expression, return its value, a function. If <form> is a symbol, return the value stored in its function box.

The form #'X is short for (FUNCTION X).

Example: (mapcar #'car '((a) (b) (c))) => (A B C)

3.3 (IF <form1> <form2> <form3>) => EXPR

Evaluate <form1>. When its value is not NIL, evaluate <form2> and otherwise evaluate <form3>. Return the value of the expression evaluated last.

<Form1> is called the Predicate of the form.

Examples: (if t 'yes 'no) => YES (if nil 'yes 'no) => NO (if (atom 'x) 'a 'b) => A

3.4 (IFNOT <form1> <form2>) => EXPR

Evaluate <form1>. When its value is not NIL, return the value of <form1>. Otherwise evaluate and return <form2>. In either case <form1> is evaluated only once.

In standard Common LISP IFNOT can be defined as:

(defmacro ifnot (p a) (let ((g (gensym))) `(let ((,g ,p)) (if ,g ,g ,a))))

Examples: (ifnot 'foo 'bar) => FOO (ifnot nil 'bar) => BAR

3.5 (LAMBDA <vars> <form1> <form2> ...) => FUN

Create a new function with the variables <vars> and the body (PROGN <form1> <form2> ...). The PROGN special form is implied, i.e.

(lambda (x) a b c)

will be interpreted as

(lambda (x) (progn a b c))

<Vars> may contain the &REST keyword. See Function Application, above.

Examples:

(lambda (x) x) ; identity function (lambda (x) (car (cdr x))) ; CADR function (lambda (&rest x) x) ; LIST function

3.6 (PROGN <form> ...) => EXPR

Evaluate all given forms from the left to the right and return the value of the rightmost expression. The special form (PROGN) evaluates to NIL.

Examples:

(progn 'a 'b 'c) => C

(progn (print 'foo) ; print FOO, then print BAR (print 'bar)) => BAR

3.7 (QUOTE <form>) => EXPR

Return <form> unevaluated.

The form 'X is an abbreviation for (QUOTE X).

Examples: (quote foo) => FOO (quote (car x)) => (CAR X) '(quote x) => (QUOTE X) '(foo bar) => (FOO BAR)

3.8 (SETQ <var> <form>) => EXPR (SETQ <var> <form> <form>) => EXPR

Evaluate <form> and store its value in the value box bound to the variable <var>. Return <var>. When <var> is not bound to any value box, a fresh box will be created and <var> will be bound to it.

If there is a third argument in SETQ, it will be ignored. For an explanation, see FSETQ.

Example: (setq foo 'bar) => BAR foo => BAR

4 Derived Special Forms

A Derived Special Form is a special form that is being transformed by the LISP system to an expression that uses only function application and the built-in (primitive) special forms listed in the previous chapter.

A function transforming a derived special form to a primitive expression is called a Macro.

A macro is defined using the FSETQ and LAMBDA special forms:

(fsetq <var> (cons 'macro <lambda>))

This form is only used internally, though, and not compatible to Common LISP. A more common and more compatible form would be

(defmacro <name> <vars> <body>)

which will be described later.

The transformation of a derived special form is called Macro Expansion. It is part of the evaluation process and happens after reading but before interpreting an expression.

The transformation is performed by passing the arguments of the derived special form to the function contained in the macro and then replacing the derived special form by the result of the macro expansion.

The result of macro expansion can contain more derived special forms, which will also be expanded.

Examples:

(fsetq kwote (cons 'macro (lambda (x) (list 'quote x))))

This macro will expand the derived special form (KWOTE FOO) to the expression (QUOTE FOO), no matter what FOO is. The value of the form is FOO.

(fsetq listq (cons 'macro (lambda x (if (null x) nil (list 'cons (list 'quote (car x)) (cons 'listq (cdr x)))))))

This macro will expand the derived special form

(listq a b c)

to (cons (quote a) (listq b c))

then to (cons (quote a) (cons (quote b) (listq c)))

then to (cons (quote a) (cons (quote b) (cons (quote c) (listq))))

and then to (cons (quote a) (cons (quote b) (cons (quote c) nil)))

which no longer contains any derived special forms. The last expression in the process is then interpreted, giving the result (A B C).

The LISTQ macro can be implemented more comprehensibly using quasiquotation -- see the definition of QUASIQUOTE in this chapter.

4.1 (AND <form> ...) => EXPR

Evaluate the given <form>s, from left to right, until a form evaluates to NIL. In this case return NIL. When none of the forms evaluates to NIL, return the value of the last form. When no forms are given, return T.

This special form implements the short-circuit logical AND.

Examples: (and) => T (and 'a 'b 'c) => C (and nil 'foo) => NIL

4.2 (COND <clause> ...) => EXPR

Each <clause> has any of these forms:

(<predicate> <form> ...) (<predicate>) (T <form> ...)

COND proceeds as follows:

The <predicate> of the first clause is evaluated. When its value is not NIL, there are two cases to distinguish:

(1) When the clause contains any <form>s, they will be evaluated from the left to the right and the value of the last form will be returned. No other clauses will be examined.

(2) When the clause contains only the predicate, the value of the predicate will be returned. No other clauses will be examined. The predicate will evaluate only once.

When the predicate of the first clause is NIL, the predicate of the next clause will be evaluated. Evaluation of COND ends when either a clause with a non-NIL predicate is found or no clauses are left to evaluate.

When there are no clauses left to evaluate, NIL is returned.

When a clause has a predicate of the form T, then the clause is assumed to be the last clause in the COND form. All subsequent clauses will be ignored.

Examples:

(cond (t 'first) (t 'second)) => FIRST (cond (nil 'a) (nil 'b) (t 'c)) => C (cond (nil 'a) ('foo 'b)) => B (cond (nil 'foo)) => NIL (cond) => NIL

4.3 (DEFMACRO <name> <vars> <body>) => <name>

Define macro <name> with the given variables and body (see Derived Special Forms). The DEFMACRO form is basically an abbreviation of

(fsetq <name> (cons 'macro (lambda <vars> <body>)))

Example: (defmacro first (x) `(car ,x))

4.5 (DEFPARAMETER <var> <form>) => <name>

Evaluate <form> and store its value in the value box bound to the variable <var>. Return <var>. When <var> is not bound to any value box, a fresh box will be created and <var> will be bound to it.

Example: (defparameter default nil)

4.5 (DEFUN <name> <vars> <body>) => <name>

Define function <name> with the given variables and body (see LAMBDA). The DEFUN form is basically an abbreviation of

(fsetq <name> (lambda <vars> <body>))

Example: (defun fourth (x) (car (cdddr x)))

4.6 (DO <bindings> <final> <body>) => EXPR

<Bindings> has the form ((<var> <init> <step>) ...) and <final> has the form (<test-expr> <final-body>).

Both <body> and <final-body> are implied PROGN forms.

A DO form evaluates as follows:

First all variables are created, <init> forms are evaluated, and their values bound to the corresponding variables, exactly like in a LET form, i.e. values are bound in parallel.

Then the <test-expr> is evaluated and if it is not NIL, <final-body> is evaluted and its result will be the result of the entire form.

If <test-expr> is false, <body> is evaluated and then each <var> is bound to its corresponding <step> form and the loop is reentered at the point where <test-expr> is evaluated.

Examples: (do ((a '(a b c d e) (cdr a))) ((null a)) (print (car a))) => NIL ; will print A B C D E

(do ((a nil (cons 'x a)) (b nil (cons a b)) (c '(1 2 3 4) (cdr c))) ((null c) b)) => ((X X X) (X X) (X) NIL)

4.7 (GENSYM) => SYMBOL

Generate a unique symbol name.

Rationale: When derived special forms expand to expressions containing local variables, these variables should be named using GENSYM. Otherwise name capturing can occur, as the following example illustrates:

(defmacro swap (x y) `(let ((L ,x)) (setq ,x ,y) (setq ,y L)))

This macro is supposed to swap the values of X and Y, but the local name L is captured when one of the names passed to it is also L, as in the form (swap L M). This form does nothing, because it sets the local L to M in the first SETQ:

(let ((L L)) (setq L M) (setq M L))

The proper way to implement the SWAP macro would be:

(defmacro swap (x y) (let ((g (gensym))) `(let ((,g ,x)) (setq ,x ,y) (setq ,y ,g))))

Example: (eq (gensym) (gensym)) => NIL

4.8 (LABELS <bindings> <body>) => EXPR

<Bindings> has the form ((<name> <vars> <fn-body>) ...) and <body> and each <fn-body> are implied PROGN forms.

Create each variable <name> and bind it to the corresponding function (lambda <vars> <fn-body>). Then evaluate <body> and return its value.

Each <fn-body> may refer to each <name>, thereby allowing to create mutually recursive functions.

Examples:

; print FOO, BAR, and BAZ (labels ((f (x) (cond (x (print (car x)) (f (cdr x)))))) (f '(foo bar baz))) => NIL

(labels ((even (x) (if (null x) t (odd (cdr x)))) (odd (x) (if (null x) nil (even (cdr x))))) (even '(1 2 3 4))) => T

4.9 (LET <bindings> <body>) => EXPR

<Bindings> has the form ((<var> <form>) ...) and <body> is an implied PROGN form.

Create all variables <var>, then evaluate the <forms> in no specific order and store their values in the corresponding variables. Finally evaluate <body> and return its value.

Examples: (let ((a 'foo) (b 'bar)) (cons a b)) => (FOO . BAR)

(let ((a 'foo)) '1 '2 a) => FOO

(let ((a '(BAR))) (let ((a 'ZZZ) (b (cons 'FOO a))) (cons a b))) => (ZZZ FOO BAR)

4.10 (LET <bindings> <body>) => EXPR

<Bindings> has the form ((<var1> <form1>) ... (<varN> <formN>) and <body> is an implied PROGN form.

Create the variable <var1>, evaluate <form1> and store its value in <var1>. With that binding in place create <var2>, evaluate <form2> , and store its value in <var2>, etc.

I.e., each <formI> evaluates in a context where all <varJ> for J<I are already bound to their corresponding values.

Examples: (let ((a 'foo) (b a)) b) => FOO

(let ((x nil) (x (cons 'C x)) (x (cons 'B x)) (x (cons 'A x))) x) => (A B C)

4.11 (OR <form> ...) => EXPR

Evaluate the given <form>s, from left to right, until a form evaluates to a value other than NIL. In this case return its value. When none of the forms evaluates to non-NIL, return NIL. When no forms are given, return NIL.

This special form implements the short-circuit logical OR.

Examples: (or) => NIL (or 'a 'b 'c) => A (or nil 'foo) => FOO (or nil nil) => NIL

4.12 (QUASIQUOTE <template>) => EXPR

Create an S-expression from a Quasiquotation template.

Quasiquotation is like quotation, but allows to "unquote" parts of the quoted S-expression, thereby inserting dynamic elements into an otherwise static template.

The following abbreviations can be used:

`expr = (QUASIQUOTE expr) ,expr = (UNQUOTE expr) ,@expr = (UNQUOTE-SPLICE expr)

The form (QUASIQUOTE template) quasiquotes an S-expression.

The form (UNQUOTE expr) unquotes an S-expression contained in a template.

The form (UNQUOTE-SPLICE expr) is like UNQUOTE, but splices the expression into the surrounding list.

Formally,

`a = (QUOTE a) `,a = a `(a b ...) = (CONS `a `(b ...)) `(,a b ...) = (CONS a `(b ...)) `(,@a b ...) = (APPEND a `(b ...))

More intuitively, QUASIQUOTE creates an (often nested) list structure and UNQUOTE replaces an element in that structure with the value of its argument. UNQUOTE-SPLICE replaces an element with multiple elements that are passed to it as a list. For instance:

`(a ,(list 'b 'c) d) => (a (b c) d)

but

`(a ,@(list 'b 'c) d) => (a b c d)

At the end of a list, a dot followed by UNQUOTE can be used in the place of UNQUOTE-SPLICE, thereby saving one application of APPEND:

`(x ,@y) = `(x . ,y)

QUASIQUOTE cannot be nested, so ``,,x is not defined (but `,`,x is).

Quasiquotation is mostly used to create expressions in macros. For instance, the KWOTE macro from the beginning of section 4 can be written as follows using QUASIQUOTE:

(defmacro kwote (x) `(quote ,x))

or even as

(defmacro kwote (x) `',x)

and the LISTQ example from the same section can be written as

(defmacro listq x (if (null x) nil `(cons (quote ,(car x)) (listq ,@(cdr x)))))

5 List Functions

5.1 (APPEND LIST ...) => LIST (NCONC LIST ...) => LIST

APPEND creates a fresh list containing the elements of all LIST arguments in the given order. All LISTs must be NIL-terminated.

NCONC is similar to APPEND, but concatenates its arguments destructively, so the original argument values will be lost.

Examples:

(append) => NIL (append '(a b) '(c d)) => (A B C D) (append '(a) '(b) '(c) '(d)) => (A B C D) (append '(a) nil nil '(b)) => (A B)

5.2 (ASSOC EXPR ALIST) => EXPR

Find an association with the key EXPR in ALIST and return it. When no association in ALIST has EXPR as its key, return NIL.

The EQUAL function is used to compare keys.

Examples:

(assoc 'b '((a . 1) (b . 2) (c . 3))) => (B . 2) (assoc 'x '((a . 1) (b . 2) (c . 3))) => NIL (assoc '(y) '((x) . 1) ((y) . 2)) => ((Y) . 2)

5.3 (CAR PAIR/NIL) => EXPR (CDR PAIR/NIL) => EXPR

CAR extracts the car part and CDR the cdr part of a pair. (CAR NIL) and (CDR NIL) are NIL.

Examples: (car '(1 . 2)) => 1 (car '(1)) => 1 (car '(1 2 3)) => 1 (cdr '(1 . 2)) => 2 (cdr '(1)) => NIL (cdr '(1 2 3)) => (2 3) (car nil) => NIL

5.4 (CAAR PAIR/NIL) => EXPR (CDDDR PAIR/NIL) => EXPR

These functions extract elements from nested pairs. These elements are extracted by the C..R functions:

((caar . cdar) . (cadr . cddr))

And these elements by C...R:

( ((caaar . cdaar) . (cadar . cddar)) . ((caadr . cdadr) . (caddr . cdddr)) )

E.g., CAAR extracts the car field of a car field, CADR the car field of a cdr field, etc. The most commonly used variants are these:

CADR the second element of a list CDDR the tail of a list after the second elt. CADDR the third element of a list CDDDR the tail of a list after the third element

Examples: (cadr '(1 2 3 4)) => 2 (cddr '(1 2 3 4)) => (3 4) (cadr nil) => NIL

(cadar '((lambda (x) t) 'foo)) => (X)

5.5 (CONS EXPR1 EXPR1) => EXPR

Create a fresh pair with EXPR1 as its car part and EXPR2 as its cdr part. All pairs created by CONS are distinct. See EQ.

Examples: (cons 'foo 'bar) => (FOO . BAR) (cons '1 '(2 3)) => (1 2 3) ; (1 . (2 3)) (cons '(1 2) '3) => ((1 2) . 3)

5.6 (LIST EXPR ...) => LIST

Create a fresh list containing the values of the given expressions.

Examples: (list) => NIL (list '1 '2 '3) => (1 2 3)

(list (cons '1 '2) (atom nil) (null 'x)) => ((1 . 2) T NIL)

5.7 (MEMBER EXPR LIST) => EXPR

Find the given EXPR in the given LIST. Return the tail of LIST that starts with the first occurrence of EXPR. When the expression is not contained in the list, return NIL.

The EQUAL function is used to compare members.

Examples: (member 'c '(a b c d e)) => (C D E) (member 'x '(a b c d e)) => NIL (member '(b) '((a) (b))) => ((B))

5.8 (REVAPPEND LIST EXPR) => EXPR (NRECONC LIST EXPR) => EXPR

REVAPPEND creates a fresh list containing the elements of LIST in reverse order and then concatenates that list to EXPR.

NRECONC is similar to REVAPPEND, but reverses and concatenates its arguments destructively, so the original argument values will be lost.

Examples:

(revappend '(1 2 3) '(a b c)) => (3 2 1 A B C) (revappend '(1 2 3) '(a . b)) => (3 2 1 A . B) (revappend '(1 2 3) 'a)) => (3 2 1 . A) (revappend '(1 2 3) nil) => (3 2 1) (revappend nil 'a) => A (revappend nil '(a b c)) => (A B C) (revappend nil nil) => NIL

5.9 (REVERSE LIST) => LIST (NREVERSE LIST) => LIST

REVERSE creates a fresh list containing the elements of LIST in reverse order. LIST must be a NIL-terminated list.

NREVERSE is similar to REVERSE, but reverses its argument destructively, so the original argument value will be lost.

Examples: (reverse '(1 2 3)) => (3 2 1) (reverse nil) => NIL

5.10 (RPLACA PAIR EXPR) => PAIR (RPLACD PAIR EXPR) => PAIR

RPLACA replaces the car part and RPLACD replaces the cdr part of the given pair with EXPR. The pair will be modified. Both functions return the modified pair

Examples: (rplaca '(foo . bar) '0) => (0 . bar) (rplacd '(foo . bar) '1) => (foo . 1)

(let ((x '(1))) ; infinite list (rplacd x x)) => (1 1 1 1 1 1 ...)

6 Higher-Order Functions

6.1 (APPLY FUN LIST) => EXPR

Apply function FUN to the given LIST of arguments and return the value delivered by the function. Basically, APPLY does

X = (cons FUN LIST)

and then evaluates X, but without evaluating the arguments in LIST again.

FUN may be a built-in function or a lambda function, but not a special operator.

Example: (apply #'cons '(a b)) => (A . B)

6.2 (FUNCALL FUN EXPR ...) => EXPR

Call the function FUN with the given expressions as arguments. Return the value returned by FUN.

FUNCALL is used to call functions that are bound in value boxes or functions that have been returned by higher-order functions.

Examples: (defun compose (f g) (lambda (x) (funcall f (funcall g x))))

(funcall (compose #'car #'cdr) '(foo bar baz)) => BAR

6.3 (MAPCAR FUN LIST1) => LIST (MAPCAR FUN LIST1 LIST2) => LIST

When one list is supplied, apply FUN to each of its elements, returning a fresh list containing the values of the function applications. I.e.:

(mapcar #'f (list a1 ... aN)) equals (list (f a1) ... (f aN))

When two lists are given, FUN is applied to elements of the lists pairwise:

(mapcar #'f (list a1 ... aN) (list b1 ... bN) equals (list (f a1 b1) ... (f aN bN))

When the lists have unequal lengths, any extra elements in the longer list will be ignored.

Examples:

(mapcar #'atom '(a (b) nil)) => (T NIL T)

(mapcar #'cons '(a b c) '(1 2 3)) => ((A . 1) (B . 2) (C . 3))

6.4 (MAPLIST FUN LIST1) => LIST (MAPLIST FUN LIST1 LIST2) => LIST

MAPLIST is like MAPCAR, but applies FUN to tails of the given lists instead of individual elements. I.e.:

(maplist #'f (list a1 ... aN)) equals (list (f (list a1 ... aN)) ... (f (list aN)))

Example:

(maplist (lambda (x) x) '(b c d e)) => ((B C D E) (C D E) (D E) (E))

(maplist #'append '(a b c) '(1 2 3)) => (((A B C 1 2 3)) ((B C 2 3)) ((C 3)))

6.5 (REMOVE-IF-NOT FUN LIST) => LIST

Return a fresh list containing all elements of LIST that satisfy the predicate FUN.

Examples:

(remove-if-not #'atom '(A (B) C (D))) => (A C)

(remove-if-not (lambda (x) (not (null x))) '(foo () bar () () baz ())) => (FOO BAR BAZ)

7 Predicates

A Predicate is a function that returns T or NIL.

7.1 (ATOM EXPR) => T or NIL

Return T, if EXPR is an atom.

Examples: (atom 'foo) => T (atom nil) => T (atom '(x)) => NIL (atom #'cadr) => T

7.2 (NULL EXPR) => T or NIL (NOT EXPR) => T or NIL

Return T, if EXPR is NIL. Both predicates are the same function, the difference between them is intensional: NULL tests whether is argument is the empty list and NOT negates the truth value of its argument.

Examples: (null (cdr '(x))) => T (not (atom 'x)) => NIL

7.3 (EQ EXPR1 EXPR2) => T or NIL

Return T, if EXPR1 and EXPR2 are the same object. This is the case if EXPR1 and EXPR2 are both

- the same symbol - NIL - bound to the same variable

In particular,

(eq (cons x nil) (cons x nil)) => NIL

and

(let ((y (cons x nil))) (eq y y)) => T

for any S-expression X.

Examples: (eq 'foo 'foo) => T (eq 'foo 'bar) => NIL (eq 'foo nil) => NIL (eq t t) => T

7.4 (EQUAL EXPR1 EXPR2) => T or NIL

Return T, if EXPR1 and EXPR2 are structurally equal. This is the case, if

- (eq EXPR1 EXPR2) => T - (equal (car EXPR1) (car EXPR2)) => T and (equal (cdr EXPR1) (cdr EXPR2)) => T

(EQ A B) implies (EQUAL A B), but the converse is not true.

Informally, two S-expressions are equal, if PRINC emits the same output for them (but this is only true, if both S-expressions have an unambiguous textual representation).

Examples: (equal '(a (b) c) '(a (b) c)) => T (equal '(a (b) c) '(a (X) c)) => NIL

7.5 (EOFP EXPR) => T or NIL

Return T, if EXPR signals the end of input, as returned by the READ function.

Example: (eofp (read)) % => T

8 Program Loading

8.1 (LOAD SYMBOL) => T

Read and evaluate expressions from the file SYMBOL. The input from the file will be processed as if typed in at the LISP prompt, but without printing any values.

Nesting LOAD more than two times will cause an error, i.e. it is possible to load a file F1 that loads a file F2, but F2 cannot load any other files.

Example: (load "program") => T

8.2 (SUSPEND SYMBOL) => T

Write a LISP image to the file SYMBOL. The file will contain the state of the LISP system at REPL level, so it can be reinstated later by loading the image. (It is not like the MACLISP SUSPEND function, which captures the entire state of the system so that it will restart where SUSPEND returned).

An image is loaded by passing its name to the LISP system when starting it (usually as a command line argument).

The default image file is named "mclisp".

Example: (suspend "mclisp") => T

9 Input and Output

These functions translate between the Internal and Textual Representations of S-expressions.

The textual representation of an S-expression is what a user types in at the LISP prompt in order to create a LISP object, like a symbol or a list. The internal representation of that object is what the LISP system uses internally to store the object -- typically a set of pointers or indexes and small integers.

9.1 (READ) => EXPR

Read the textual representation of one object from the current input source, convert it to internal representation and return it.

Note that the value returned by READ on the REPL will then be printed by PRINT (see below), which converts it back to textual representation. Hence the internal representation of an object will never be visible to the programmer.

READ will skip over leading white space characters and comments while reading input. It will only return when a complete S-expression has been read. When reading lists or pairs, the input may span multiple lines.

READ will expand abbreviations like 'X and #'X.

When no input is available on the current input source, READ will return a special object called the End of Transmission Marker (or EOT marker). The EOT marker will print as <EOT> at the LISP prompt.

An EOT marker can be generated by pressing Control-D ("Control" and "d") or Control-Z on the keyboard. MICRO COMMON LISP will also interpret the "%" character as an EOT marker.

Examples: (read) foo => FOO

(read) (a b c) => (A B C)

(read) 'x => (QUOTE X)

(read) % => <EOT>

9.2 (PRIN EXPR) => EXPR (PRINC EXPR) => EXPR (PRINT EXPR) => EXPR

All of these functions print the textual representation of the given S-expression on the output device. They return the object being printed.

Note that none of these functions slashifies its output, so a slashified symbol printed by them might not be readable by READ or might be a different symbol after reading it back.

PRINC just prints EXPR. PRIN prints a trailing blank after EXPR. PRINT advances to the next line before printing EXPR.

PRIN is not a standard Common LISP function, but it is very useful for printing lines consisting of multiple atoms.

Example: (princ 'foo) => FOO ; prints "foo"

9.3 (TERPRI) => NIL

Print a newline character. Return T, because there are no characters.

Example: (terpri) => T

10 Introspection Functions

10.1 (MACRO-FUNCTION SYMBOL) => FUN

Return the current macro function of the given symbol, or NIL if the symbol is not bound to a macro via its function box. The macro function (or macro expander) is the function that transforms a special form at macro expansion time.

The macro functions of MICRO COMMON LISP are not compatible to Common LISP macro functions. See the last example below.

Examples:

(macro-function 'undefined) => NIL (macro-function 'cons) => NIL (macro-function 'let)) => <FUNCTION>

(funcall (macro-function 'let) '((a 1) (b 2)) 'body) => ((LAMBDA (B A) BODY) 2 1)

10.2 (MACROEXPAND-1 EXPR) => EXPR

If (CAR EXPR) is a macro, expand the macro and return the expanded form. Otherwise return EXPR unchanged. The macro expansion performed by MACROEXPAND-1 is non-recursive.

Examples:

(macroexpand-1 'foo) => FOO

(macroexpand-1 '(let ((x 'foo)) x)) => ((LAMBDA (X) X) (QUOTE FOO))

(macroexpand-1 '(let ((a '1) (b '2)) t)) => (LET ((A '1)) (LET ((B '2)) T))

11 Misc. Functions

11.1 (ERROR SYMBOL) => UNDEFINED (ERROR SYMBOL EXPR) => UNDEFINED

Signal an error by printing a message and aborting the computation in progress. The message will consist of a question mark and the given SYMBOL. When a second argument is given, it will print after the SYMBOL, separated from it by a colon. E.g.

When an error is signalled while loading a file, the line number in which the error occurs is printed after the question mark.

(error 'don't do this!) will print ? don't do this!

(error 'wrong 'foo) will print ? wrong: foo

The ERROR function delivers no value, because it never returns.

Example: (if (atom x) (error 'need a list x) (do-something-with x))

11.2 (GC) => NIL (GC EXPR) => NIL

Perform a garbage collection. Note that garbage collections are triggered automatically. This function merely informs the programmer about memory usage.

When NIL is passed to GC, all subsequent automatic collections will be silent, and when a non-NIL value is passed to GC, subsequent collections will be verbose.

The value returned by GC is an uninterned symbol.

Example: (gc) => number of free nodes

12 The REPL

The Read Eval Print Loop (REPL) is the interface to the LISP system. It prints a prompt (), reads an expressions via READ, evaluates it, prints its value using PRINT, and starts over.

12.1 Batch Mode

When the MICRO COMMON LISP interpreter is started in "batch" mode, input is read from SYSIN (stdin) and output is written to SYSOUT (stdout). Batch mode is activated by passing the command line argument "-" to the interpreter.

In Batch mode, input and output of the LISP system can be redirected to files. Command line editing will not work, and pressing Control-C will exit the interpreter immediately. The interpreter will also exit when the end of its input is reached. (Or when an end-of-text indicator is entered at the keyboard).

Batch mode is intended for running the system in non-interactive way (for batch processing).

12.2 Interactive Mode

While the REPL is reading input in interactive mode, the following keys will have special functions:

Control-B move cursor left/back Control-F move cursor right/forward Control-A move cursor to beginning of line Control-E move cursor to end of line

Control-D delete character Control-H delete char. on left (also backspace)

Control-P rotate through last three input lines

Control-C abort all input, start over Control-U clear current input line

Control-L clear screen

Control-D (on an empty line) exit

Once a computation is in progress, it can be aborted by pressing Control-C.

The value returned by a computation will be bound to the variable , so it can be used in the expression typed next:

(cons '1 '(2 3)) (1 2 3) (cons '0 ) (0 1 2 3)

To end the LISP session, press Control-D or enter a % sign, both on an empty input line with no lists open.

13 Difference to Common LISP

Of course the most obvious difference is that MICRO COMMON LISP is a tiny and purely symbolic subset of Common LISP. However, there are also some more subtle differences.

13.1 Extra Special Forms

The FSETQ and IFNOT special forms do not exist in Common LISP. These symbols cannot be redefined in MICRO COMMON LISP.

13.2 DEFPARAMETER

When (DEFPARAMETER X Y) is used inside of a function that defines a local variable X, the binding of the LOCAL variable will be changed and no global variable will be created or modified. This is a bug.

13.3 MACRO-FUNCTION

The functions returned by MACRO-FUNCTION expect exactly the arguments specified in the argument list of DEFMACRO, while Common LISP expects the full form to be expanded and a NIL environment.

MACRO-FUNCTION will also retrieve functions from locally defined macros, which it will not do in Common LISP.

13.4 PRINT

PRINT uses PRINC instead of PRIN1. There is no PRIN1 function.

13.5 Extra Functions

MICRO COMMON LISP has some extra functions that are not defined in Common LISP, but those can be redefined without affecting the proper functioning of the system.


contact | privacy