Bettina Schimanski wrote:
> I apologize for bothering you with what must be such a simple question
> to all of you but I could really use some good "beginners" advice. I am
> a graduate student in the process of teaching myself Common Lisp with
> Allegro CL Professional 5.0 and would like to make a copy of an array. I
> have been using setf, but just realized that this really just makes the
> new variable point to the old array and so when the new array is changed
> so is the old, which I would really like to avoid (a common programming
> problem to avoid). I can go through tediously and
>
> (setf (aref new-array row col) (aref old-array row col))
>
> for every single element, but I'm sure there is a more sophisticated way
> which I would like to learn. I have found a copy function for lists,
> readtables, trees, sequences, but not for arrays...
Since you have discovered copy-seq, you probably know it does what you
want but only for one-dimensional arrays (vectors). You have implied by
your example above that you're interested in two-dimensional arrays, for
which an additional trick is needed:
; Here's your original two-dimensional array:
(setf original-array (make-array '(10 20)))
(copy-seq original-array) --> ERROR, because it's not a sequence
(setf linearization-array (make-array 200 :displaced-to original-array))
; linearization-array is identical with original-array, but it's
; accessible as if it were one-dimensional. Changes to
; linearization-array will affect original-array.
(setf linear-copied-array (copy-seq linearization-array))
; This is a true copy--changes here won't affect the first two.
; Copy-seq works because this is considered a sequence.
(setf final-copied-array (make-array '(10 20) :displaced-to
linear-copied-array))
; This step just makes linear-copied-array be accessible as if it were
; two-dimensional.
Note that although we've created 3 new arrays in addition to your
original, only one of them consed a significant amount of memory. So
there's no real memory penalty other than the obvious cost of a copy.
The trick of being able to access an array as either one-dimensional or
multi-dimensional can be quite handy in and of itself. Some other useful
functions that make this trick more dynamic are array-row-major-index and
row-major-aref.
> "Ansi Common Lisp" by Paul Graham
> "Common Lisp" by Guy Steele Jr.
> "The Common Lisp Companion" by Timothy Koschmann
> "Lisp, 3rd Edition" by Patrick Winston and Berthold Horn
I've also found Slade's "Object Oriented Common Lisp" and Norvig's
"Paradigms of Artificial Intelligence Programming : Case Studies in Common
Lisp" useful, and if you want to dig more deeply into Common Lisp
(especially macros), study Graham's "On Lisp". It's out of print now but
it's available as a free download from www.paulgraham.com.
Shannon Spires
<sandia.gov at svspire>