3.2. Compilation
Prev | Chapter 3. Evaluation and Compilation | Next

## 3.2. Compilation [sec_3-2]

### 3.2.1. Compiler Terminology [sec_3-2-1]

CLISP compiles to platform-independent bytecode.

### 3.2.2. Compilation Semantics [sec_3-2-2]

#### 3.2.2.1. Compiler Macros [sec_3-2-2-1]

Compiler macros are expanded in the compiled code only, and ignored by the interpreter.

#### 3.2.2.2. Minimal Compilation [sec_3-2-2-2]

When a `DEFUN` form is `EVAL`uated, the macros used there are expanded, so they must be already defined, and their (re)definition does not affect functions which are already defined.

This means that even the interpreted code is minimally compiled in CLISP.

#### 3.2.2.3. Semantic Constraints [sec_3-2-2-3]

Non-conforming code that does not follow the rule

> “Special proclamations for dynamic variables must be made in the compilation environment.”

can produce quite unexpected results, e.g., observable differences between compiled and interpreted programs:

    (defun adder-c (value) (declare ((COMPILE))) (lambda (x) (+ x value)))
    ⇒ ADDER-C	; compiled function; value is lexical
    (defun adder-i (value) (lambda (x) (+ x value)))
    ⇒ ADDER-I	; interpreted function; value is lexical
    (setq add-c-10 (adder-c 10))
    ⇒ ADD-C-10	; compiled function
    (setq add-i-10 (adder-i 10))
    ⇒ ADD-I-10	; interpreted function
    (funcall add-c-10 32)
    ⇒ 42	; as expected
    (funcall add-i-10 32)
    ⇒ 42	; as expected
    (defvar value 12)
    ⇒ VALUE	; affects ADDER-I and ADD-I-10 but not ADDER-C and ADD-C-10
    (funcall add-c-10 32)
    ⇒ 42	; as before
    (funcall add-i-10 32)
    ⇒ 44	; value is now dynamic!

Non-conformance. The code shown above has a `SPECIAL` proclamation (by `DEFVAR`) for the variable `value` in the execution environment (before the last two `FUNCALL`s) but not in the compilation environment: at the moment the `ADDER-I` function is defined, `value` is not known to be a `SPECIAL` variable. Therefore the code is not conforming.

##### Rationale

The function `ADD-C-10` was compiled before `value` was declared `SPECIAL`, so the symbol `value` was eliminated from its code and the `SPECIAL` declaration did not affect the return value (i.e., `(funcall add-c-10 32)` always returned 42).

On the opposite, function `ADDER-I` was not compiled, so `ADD-I-10` was interpreted. Whenever `ADD-I-10` is executed, its definition is interpreted all over again. Before `DEFVAR`, `value` is evaluated as a lexical (because is is not declared `SPECIAL` yet), but after `DEFVAR`, we see a globally `SPECIAL` symbol `value` which can have only a global `SYMBOL-VALUE` (not a local binding), and thus we are compelled to evaluate it to 12.

This behavior was implemented intentionally to ease interactive development, because usually the `ADDER-I` above would be followed by a (forgotten) `DEFVAR`.

When a user compiles a program, the compiler is allowed to remember the information whether a variable was `SPECIAL` or not, because that allows the compiler to generate more efficient code, but in interpreted code, when the user changes the state of a variable, he does not want to re-evaluate all `DEFUN`s that use the variable.

[ANSI CL standard] gives the implementation freedom regarding interpreted evaluation, how much it wants to remember / cache, and how much it wants to evaluate according the current environment, if the environment has changed. CLISP implements ad-hoc look-up for variables (but not for macros, see Section 3.2.2.2, “Minimal Compilation ”).

### 3.2.3. Definition of Similarity [sec_3-2-4-2-2]

Hash tables are externalizable objects.

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
3.1. Evaluation | Home | 3.3. Declarations