User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:special_operators:load-time-value [2017/05/01 21:00] (current)
Line 1: Line 1:
 +====== Special Operator LOAD-TIME-VALUE ======
 +
 +====Syntax====
 +  * load-time-value //form ''&​optional''​ read-only-p//​ → //object//
 +
 +====Arguments and Values====
 +  * //form// - a //​[[CL:​Glossary:​form]]//;​ evaluated as described below.
 +  * //​read-only-p//​ - a //​[[CL:​Glossary:​boolean]]//;​ not evaluated.
 +  * //object// - the //​[[CL:​Glossary:​primary value]]// resulting from evaluating //form//.
 +
 +====Description====
 +
 +**load-time-value** provides a mechanism for delaying evaluation of //form// until the expression is in the run-time environment;​ see section {\secref\Compilation}.
 +
 +//​Read-only-p//​ designates whether the result can be considered a //​[[CL:​Glossary:​constant object]]//. If **[[CL:​Constant Variables:​t]]**,​ the result is a read-only quantity that can, if appropriate to the //​[[CL:​Glossary:​implementation]]//,​ be copied into read-only space and/or //​[[CL:​Glossary:​coalesce|coalesced]]//​ with //​[[CL:​Glossary:​similar]]//​ //​[[CL:​Glossary:​constant object|constant objects]]// from other //​[[CL:​Glossary:​program|programs]]//​. If **[[CL:​Constant Variables:​nil]]** (the default), the result must be neither copied nor coalesced; it must be considered to be potentially modifiable data.
 +
 +If a **load-time-value** expression is processed by **[[CL:​Functions:​compile-file]]**,​ the compiler performs its normal semantic processing (such as macro expansion and translation into machine code) on //form//, but arranges for the execution of //form// to occur at load time in a //​[[CL:​Glossary:​null lexical environment]]//,​ with the result of this //​[[CL:​Glossary:​evaluation]]//​ then being treated as
 +
 +a //​[[CL:​Glossary:​literal object]]// at run time. It is guaranteed that the evaluation of //form// will take place only once when the //​[[CL:​Glossary:​file]]//​ is //​[[CL:​Glossary:​load|loaded]]//,​ but the order of evaluation with respect to the evaluation of //​[[CL:​Glossary:​top level forms]]// in the file is //​[[CL:​Glossary:​implementation-dependent]]//​. ​
 +
 +If a **load-time-value** expression appears within a function compiled with **[[CL:​Functions:​compile]]**,​ the //form// is evaluated at compile time in a //​[[CL:​Glossary:​null lexical environment]]//​. The result of this compile-time evaluation is treated as a //​[[CL:​Glossary:​literal object]]// in the compiled code.
 +
 +If a **load-time-value** expression is processed by **[[CL:​Functions:​eval]]**,​ //form// is evaluated in a //​[[CL:​Glossary:​null lexical environment]]//,​ and one value is returned. Implementations that implicitly compile (or partially compile) expressions processed by **[[CL:​Functions:​eval]]** might evaluate //form// only once, at the time this compilation is performed.
 +
 +If the //​[[CL:​Glossary:​same]]//​ //​[[CL:​Glossary:​list]]//​ ''​(load-time-value //​form//​)''​ is evaluated or compiled more than once, it is //​[[CL:​Glossary:​implementation-dependent]]//​ whether //form// is evaluated only once or is evaluated more than once. This can happen both when an expression being evaluated or compiled shares substructure,​ and when the //​[[CL:​Glossary:​same]]//​ //​[[CL:​Glossary:​form]]//​ is processed by **[[CL:​Functions:​eval]]** or **[[CL:​Functions:​compile]]** multiple times. Since a **load-time-value** expression can be referenced in more than one place and can be evaluated multiple times by **[[CL:​Functions:​eval]]**,​ it is //​[[CL:​Glossary:​implementation-dependent]]//​ whether each execution returns a fresh //​[[CL:​Glossary:​object]]//​ or returns the same //​[[CL:​Glossary:​object]]//​ as some other execution. Users must use caution when destructively modifying the resulting //​[[CL:​Glossary:​object]]//​.
 +
 +If two lists ''​(load-time-value //​form//​)''​ that are the //​[[CL:​Glossary:​same]]//​ under **[[CL:​Functions:​equal]]** but are not //​[[CL:​Glossary:​identical]]//​ are evaluated or compiled, their values always come from distinct evaluations of //form//.
 +
 +Their //​[[CL:​Glossary:​values]]//​ may not be coalescedunless //​read-only-p//​ is **[[CL:​Constant Variables:​t]]**.
 +
 +====Examples====
 +<​blockquote>​
 +;;; The function INCR1 always returns the same value, even in different
 +;;; images. The function INCR2 always returns the same value in a given 
 +;;; image, but the value it returns might vary from image to image.
 +([[CL:​Macros:​defun]] incr1 (x) ([[CL:​Functions:​math-add|+]] x #​.([[CL:​Functions:​random]] 17))) <​r>​INCR1</​r>​
 +([[CL:​Macros:​defun]] incr2 (x) ([[CL:​Functions:​math-add|+]] x (load-time-value ([[CL:​Functions:​random]] 17)))) <​r>​INCR2</​r>​
 +
 +;;; The function FOO1-REF references the nth element of the first of the 
 +;;; *FOO-ARRAYS* that is available at load time. It is permissible for that
 +;;; array to be modified (e.g., by SET-FOO1-REF);​ FOO1-REF will see the updated
 +;;; values.
 +([[CL:​Macros:​defvar]] *foo-arrays* ([[CL:​Functions:​list]] ([[CL:​Functions:​make-array]] 7) ([[CL:​Functions:​make-array]] 8)))
 +<​r>​*FOO-ARRAYS*</​r>​
 +([[CL:​Macros:​defun]] foo1-ref (n)
 +  ([[Cl:​Functions:​aref]] (load-time-value ([[CL:​Functions:​first]] *my-arrays*) [[CL:​Constant Variables:​nil]]) n))
 +<​r>​FOO-1-REF</​r>​
 +([[CL:​Macros:​defun]] set-foo1-ref (n val)
 +  ([[CL:​Macros:​setf]] ([[Cl:​Functions:​aref]] (load-time-value ([[CL:​Functions:​first]] *my-arrays*) [[CL:​Constant Variables:​nil]]) n) val))
 +<​r>​SET-FOO1-REF</​r>​
 +
 +;;; The function BAR1-REF references the nth element of the first of the 
 +;;; *BAR-ARRAYS* that is available at load time. The programmer has promised
 +;;; that the array will be treated as read-only, so the system can copy or 
 +;;; coalesce the array.
 +([[CL:​Macros:​defvar]] *bar-arrays* ([[CL:​Functions:​list]] ([[CL:​Functions:​make-array]] 7) ([[CL:​Functions:​make-array]] 8)))
 +<​r>​*BAR-ARRAYS*</​r>​
 +([[CL:​Macros:​defun]] bar1-ref (n)
 +  ([[Cl:​Functions:​aref]] (load-time-value ([[CL:​Functions:​first]] *my-arrays*) [[CL:​Constant Variables:​t]]) n))
 +<​r>​BAR1-REF</​r>​
 +
 +;;; This use of LOAD-TIME-VALUE permits the indicated vector to be coalesced
 +;;; even though NIL was specified, because the object was already read-only ​
 +;;; when it was written as a literal vector rather than created by a 
 +;;; constructor. User programs must treat the vector v as read-only.
 +([[CL:​Macros:​defun]] baz-ref (n)
 +  ([[CL:​Special Operators:​let]] ((v (load-time-value #(A B C) [[CL:​Constant Variables:​nil]])))
 +    ([[CL:​Functions:​values]] ([[CL:​Functions:​svref]] v n) v)))
 +<​r>​BAZ-REF</​r>​
 +
 +;;; This use of LOAD-TIME-VALUE permits the indicated vector to be coalesced ​
 +;;; even though NIL was specified in the outer situation because T was 
 +;;; specified in the inner situation. User programs must treat the vector v as
 +;;; read-only.
 +([[CL:​Macros:​defun]] baz-ref (n)
 +  ([[CL:​Special Operators:​let]] ((v (load-time-value (load-time-value ([[CL:​Functions:​vector]] 1 2 3) [[CL:​Constant Variables:​t]]) [[CL:​Constant Variables:​nil]])))
 +    ([[CL:​Functions:​values]] ([[CL:​Functions:​svref]] v n) v)))
 +<​r>​BAZ-REF</​r>​
 +</​blockquote>​
 +
 +====Affected By====
 +None.
 +
 +====Exceptional Situations====
 +None.
 +
 +====See Also====
 +**[[CL:​Functions:​compile-file|Function COMPILE-FILE]]**,​ **[[CL:​Functions:​compile|Function COMPILE]]**,​ **[[CL:​Functions:​eval|Function EVAL]]**, {\secref\MinimalCompilation},​ {\secref\Compilation}
 +
 +====Notes====
 +**load-time-value** must appear outside of quoted structure in a "for //​[[CL:​Glossary:​evaluation]]//"​ position. In situations which would appear to call for use of **load-time-value** within a quoted structure, the //​[[CL:​Glossary:​backquote]]//​ //​[[CL:​Glossary:​reader macro]]// is probably called for; see section {\secref\Backquote}.
 +
 +Specifying **[[CL:​Constant Variables:​nil]]** for //​read-only-p//​ is not a way to force an object to become modifiable if it has already been made read-only. It is only a way to say that, for an object that is modifiable, this operation is not intended to make that object read-only.
 +
 +\issue{LOAD-TIME-EVAL:​R**3-NEW-SPECIAL-FORM}