Am Mittwoch, 05.03.03 um 16:27 Uhr schrieb rif:
> (declaim (optimize (speed 3) (debug 0) (safety 0)))
>
> (defun copy-frame (frame n)
During the first compilation run, this frame is a lexical variable, and
hence the compiler has all information it needs in order to optimize at
will, since lexical variables are inaccessible from the outside, so the
following declaration will invariably hold:
> (declare (type (simple-array double-float) frame))
> (declare (type fixnum n))
> (let ((new-frame (make-array n :element-type 'double-float)))
> (dotimes (i n)
> (declare (type fixnum i))
> (setf (aref new-frame i) (aref frame i)))
> new-frame))
>
> (defvar frame (make-array 10 :element-type 'double-float))
This globally declaims frame to be a special variable. During the
first compilation run this doesn't affect the frame in copy-frame,
since this has already been compiled, without the special declaration
being in effect. However during the second and later compilation runs,
frame in copy-frame will be the special variable frame. Since special
variable bindings can be modified by anything called during the
execution of the binding form, frame could be side-effected by code
which isn't bound by the type declaration in copy-frame, hence the
compiler can't make as many assumptions as it could previously. Also,
special variable access is usually slower than lexical vars, since the
latter can be kept in registers, whereas the former can't.
Note that besides mucking up your optimizations, special variables have
very different semantics from lexical variables, hence your defvar
frame isn't at all likely to be what you want. For example, during the
execution of copy-frame the "global" variable frame is rebound to the
value passed into copy-frame, and this is visible to functions called
from copy-frame.
The general rule is to never, ever name your special/global variables
the same as any lexical variable names that are likely to crop up.
Hence the tradition in Lisp to name them with leading and trailing *,
i.e.
(defvar *frame* ...)
It should be noted that Common Lisp has no global, lexical variables,
only global, special variables.
Note that there are cases where people do intentionally use special
variables as function parameters, e.g.
(defun mydribble (&optional (*standard-output* *error-output*))
;; Any I/O functions (transitively) called from here see
*standard-output*
;; rebound to the argument value passed in.
(write-string "Foo: ")
(print 42))
This is equivalent to
(defun mydribble (&optional (output-stream *error-output*))
(let ((*standard-output* output-stream))
;; Any I/O functions (transitively) called from here see
*standard-output*
;; rebound to the argument value passed in.
(write-string "Foo: ")
(print 42)))
Regs, Pierre.
--
Pierre R. Mai <[EMAIL PROTECTED]> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein