3.2. Compilation [sec_3-2]

3.2.1. Compiler Terminology
3.2.1.1. Just-In-Time Native Compilation
3.2.2. Compilation Semantics
3.2.2.1. Compiler Macros
3.2.2.2. Minimal Compilation
3.2.2.3. Semantic Constraints
3.2.3. Definition of Similarity
3.2.4. Exceptional Situations in the Compiler

3.2.1. Compiler Terminology [sec_3-2-1]

CLISP compiles to platform-independent bytecode.

3.2.1.1. Just-In-Time Native Compilation

Platform Dependent: only in CLISP built with GNU lightning

The code compiled to bytecodes with optimization levels

(OR (>= 0 SPACE) (<= 1 SPEED))

(by COMPILE, COMPILE-FILE, or (COMPILE)) will be just-in-time (i.e., on the first execution) compiled to native code using GNU lightning.

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 EVALuated, 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-Ccompiled function; value is lexical
(defun adder-i (value) (lambda (x) (+ x value)))
⇒ ADDER-Iinterpreted function; value is lexical
(defparameter add-c-10 (adder-c 10))
⇒ ADD-C-10compiled function
(defparameter add-i-10 (adder-i 10))
⇒ ADD-I-10interpreted function
(funcall add-c-10 32)
⇒ 42as expected
(funcall add-i-10 32)
⇒ 42as expected
(defvar value 12)
⇒ VALUEaffects ADDER-I and ADD-I-10 but not ADDER-C and ADD-C-10
(funcall add-c-10 32)
⇒ 42as before
(funcall add-i-10 32)
⇒ 44value 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 FUNCALLs) 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 DEFUNs 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 re-evaluate according the current environment, if it 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.

3.2.4. Exceptional Situations in the Compiler [sec_3-2-5]

Both COMPILE and EVAL may SIGNAL the EXT:SOURCE-PROGRAM-ERROR CONDITION which derives from PROGRAM-ERROR and which contains additional slots with accessors

EXT:SOURCE-PROGRAM-ERROR-FORM
Returns the whole form in which the ERROR was SIGNALed
EXT:SOURCE-PROGRAM-ERROR-DETAIL
Returns the specific (usually small) part of the above which triggered the ERROR

These notes document CLISP version 2.49Last modified: 2010-07-07