The LOCALLY special form specifies declarations for code that is
lexically contained in this form. When you write (COMPILE NIL 'F)
the definition of F is not contained in the LOCALLY form;
therefore the declarations in effect at the COMPILE form are
irrelevant.
In other words, what matters is the declarations in effect at the
*definition* of F.
What you appear to want is some mechanism that establishes some
optimization settings for the code being compiled by the COMPILE
function, with dynamic extent. Such a mechanism cannot exist as an
override because, as mentioned above, what matters according to
CLHS 3.3 is the declarations in effect at the *definition* of F.
But what you can do is to change the defaults:
(PROG2
(DECLAIM (OPTIMIZE ...))
(COMPILE NIL 'F)
(DECLAIM (OPTIMIZE default-settings)))
Note that even this will not work across implementations, because
of the distinction between compile environment and execution
environment that some implementations make. See CLHS:DECLAIM
for details.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> it is not clear why declaim changes the result of compile while locally does not.
DECLAIM is a macro wrapper around PROCLAIM. PROCLAIM establishes the declarations in the global environment. So DECLAIM and PROCLAIM have an effect with indefinite extent, not scoped. This is why (COMPILE 'F) may actually see these changed declarations in the global environment.
Whether it actually does, depends on whether COMPILE takes the source code of F and considers it in the current global environment (changed by DECLAIM), or whether it takes a "frozen" form of the source code of F, ignoring the current global environment. Both approaches are allowed, see CLHS 3.2.2.3.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It says "Conforming programs should not be written using any additional assumptions about consistency between the run-time environment and the startup, evaluation, and compilation environments." The preceding paragraphs don't mention OPTIMIZE declarations. Therefore the COMPILE function is free to take the OPTIMIZE declarations from the evaluation environment or the compilation environment of F.
But that's only a side issue. The central argumentation is that OPTIMIZE qualities are determined by declarations, and such declarations have lexical scoping. See CLHS 3.3.4:
"Declarations that do not apply to bindings can only appear as free declarations."
"the scope of a free declaration includes only the body subforms of the form at whose head it appears, and no other subforms."
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
not quite.
(locally (declare (optimize (safety X))) (disassemble (lambda (a) (aref a 0) 1)))
and
> (locally (declare (optimize (safety 3))) (funcall (compile nil (lambda(a) (aref a 0) 1)) 3))
*** - AREF: argument 3 is not an array
> (locally (declare (optimize (safety 0))) (funcall (compile nil (lambda(a) (aref a 0) 1)) 3))
1
works fine, but
(defparameter f (lambda (a) (aref a 0) 1))
(disassemble (locally (declare (optimize (safety X))) (compile nil f)))
prints the same regardless of X
this is NOT an ANSI compliance issue because the eval and compile environments differ,
see http://clisp.podval.org/impnotes/compilation.html#semantic-constraints
It is not a bug, but rather the expected behaviour.
Please remember to distinguish "scope" and "extent".
http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html
The LOCALLY special form specifies declarations for code that is
lexically contained in this form. When you write (COMPILE NIL 'F)
the definition of F is not contained in the LOCALLY form;
therefore the declarations in effect at the COMPILE form are
irrelevant.
In other words, what matters is the declarations in effect at the
*definition* of F.
What you appear to want is some mechanism that establishes some
optimization settings for the code being compiled by the COMPILE
function, with dynamic extent. Such a mechanism cannot exist as an
override because, as mentioned above, what matters according to
CLHS 3.3 is the declarations in effect at the *definition* of F.
But what you can do is to change the defaults:
(PROG2
(DECLAIM (OPTIMIZE ...))
(COMPILE NIL 'F)
(DECLAIM (OPTIMIZE default-settings)))
Note that even this will not work across implementations, because
of the distinction between compile environment and execution
environment that some implementations make. See CLHS:DECLAIM
for details.
it is not clear why declaim changes the result of compile while locally does not.
> it is not clear why declaim changes the result of compile while locally does not.
DECLAIM is a macro wrapper around PROCLAIM. PROCLAIM establishes the declarations in the global environment. So DECLAIM and PROCLAIM have an effect with indefinite extent, not scoped. This is why (COMPILE 'F) may actually see these changed declarations in the global environment.
Whether it actually does, depends on whether COMPILE takes the source code of F and considers it in the current global environment (changed by DECLAIM), or whether it takes a "frozen" form of the source code of F, ignoring the current global environment. Both approaches are allowed, see CLHS 3.2.2.3.
I don't see anything in
http://www.lispworks.com/documentation/HyperSpec/Body/03_bbc.htm
which would imply that.
It says "Conforming programs should not be written using any additional assumptions about consistency between the run-time environment and the startup, evaluation, and compilation environments." The preceding paragraphs don't mention OPTIMIZE declarations. Therefore the COMPILE function is free to take the OPTIMIZE declarations from the evaluation environment or the compilation environment of F.
But that's only a side issue. The central argumentation is that OPTIMIZE qualities are determined by declarations, and such declarations have lexical scoping. See CLHS 3.3.4:
"Declarations that do not apply to bindings can only appear as free declarations."
"the scope of a free declaration includes only the body subforms of the form at whose head it appears, and no other subforms."