micromoog <micromoog@gmail.com> wrote:
+---------------
| Thanks again; I think I've almost got it:
| 1) At read-time (when the defun is evaluated), the #(0) expression
| creates an array object, initialized to contain the value #(0). This
| object has no name and is only accessible from within that function
| (in fact, only from within the expression which contains it)...
+---------------
Not always!! If you COMPILE-FILE the file containing the function,
and there's another function with the "same"[1] constant in it, the
compiler is permitted to "coalesce" the two constants, which can
cause unwanted coupling between the two functions. Here's an actual
example [though note that I changed your vector #(0) to a list '(0)
and changed AREF to NTH, since the compiler I was using didn't coalesce
the two constant vectors (but did coalesce the two constant lists)]:
$ cat foo.lisp
(defun foo (n)
(let ((x '(0)))
(incf (nth n x))))
(defun bar (m)
(let ((y '(0)))
(incf (nth m y))))
$ my_favorite_common_lisp
...chatter...
> (compile-file "foo")
...more chatter...
#p"/u/rpw3/src/cmd/qdl/foo.x86f"
NIL
NIL
> (load *)
; Loading #p"/u/rpw3/src/cmd/qdl/foo.x86f".
T
> (foo 0)
1
> (foo 0) ; Calling FOO1 twice shows the problem you saw.
2
> (bar 0) ; Now call the *other* function!!
3
>
Clearly, the two functions are sharing the same '(0)!!
Since modifying a constant [as above] is "undefined" behavior,
worse things could happen. YMMV...
-Rob
[1] "Same" here is defined by CLHS 3.2.4 "Literal Objects in Compiled
Files", 3.2.4.2.2 "Definition of Similarity", and 3.2.4.4 "Additional
Constraints on Externalizable Objects", which contains the rules on
coalescing similar objects.
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607