From: Wei Jen Yeh
Subject: ,@ not working
Date: 
Message-ID: <18728@ector.cs.purdue.edu>
Hello,
  Can someone see what's happening here?  The following are some simple
functions that copy arrays of any dimensions.  When compiling the code (using
AKCL) or envoking copy_array after the .lsp is loaded, the @ char seems to be
causing problems.  The compilation gave the message below.  And calling
copy_array had similar error msg.

Error: PREFIX is not of type LIST.
Fast links are on: do (use-fast-links nil) for debugging
Error signalled by SYSTEM::SETF-HELPER.
Backtrace: compiler::t1expr > funcall > funcall > SYSTEM::SETF-HELPER

I tried it using both akcl-1-615 and akcl1-492.
BTW, does anobody have a better array copier? (besides reading back a print
form of the array)

Thanks in advance for any help.

Wei Jen Yeh                      ···@cs.purdue.edu
                                 Department of Computer Science
                                 Purdue University
                                 West Lafayette, Indiana

(defun copy_array (array)
  (let* ((dims (array-dimensions array))
         (new_array (funcall #'make-array dims)))
        (copy_array_elmts new_array array NIL dims)
        new_array))

(defmacro mset (array indices)
  `(aref ,array ,@indices))

(defun copy_array_elmts (new old prefix rest_dims)
  (if (null rest_dims)
      (setf (mset new prefix) (mset old prefix))
      (let ((n (car rest_dims))
            (i 0))
           (loop (if (= i n)
                     (return T))
                 (copy_array_elmts new old
                                   (append prefix (list i)) (cdr rest_dims))
                 (setq i (+ i 1))))))

From: Thomas A. Russ
Subject: Re: Copying an array (Was: ,@ not working)
Date: 
Message-ID: <21554@venera.isi.edu>
This might be a bit crufty, but how about this for copying arrays:

(defun copy-array (array)
  (let* ((total-size (array-total-size array))
	 (new-array (funcall #'make-array (array-dimensions array)))
	 (temp-old (make-array total-size :displaced-to array
					; Element type MUST match
			       :element-type (array-element-type array)))
	 (temp-new (make-array total-size :displaced-to new-array)))
    (dotimes (i total-size)
	(setf (aref temp-new i) (aref temp-old i)))
    new-array))

Note that if you use the new (CLtL2) function ROW-MAJOR-AREF, you can
dispense with the use of displaced arrays entirely:

(defun copy-array (array)
  (let ((new-array (funcall #'make-array (array-dimensions array))))
    (dotimes (i (array-total-size array))
	(setf (row-major-aref new-array i)
	      (row-major-aref array i)))
    new-array))
--

Thomas A. Russ                                             ···@isi.edu    
USC/ISI, 4676 Admiralty Way, Marina del Rey, CA 90292      (310) 822-1511
From: Barry Margolin
Subject: Re: ,@ not working
Date: 
Message-ID: <vg8knINNo7b@early-bird.think.com>
In article <·····@ector.cs.purdue.edu> ···@cs.purdue.EDU (Wei Jen Yeh) writes:
>Hello,
>  Can someone see what's happening here?  The following are some simple
>functions that copy arrays of any dimensions.  When compiling the code (using
>AKCL) or envoking copy_array after the .lsp is loaded, the @ char seems to be
>causing problems.  The compilation gave the message below.  And calling
>copy_array had similar error msg.

>Error: PREFIX is not of type LIST.

>(defmacro mset (array indices)
>  `(aref ,array ,@indices))
>
>(defun copy_array_elmts (new old prefix rest_dims)
>  (if (null rest_dims)
>      (setf (mset new prefix) (mset old prefix))

Macro expansion happens at compile time; the arguments to the macro are
pieces of the *source* code.  Thus, the value of INDICES is the symbol
PREFIX, and you can't splice a symbol into a list (you can only splice
lists).  The fact that PREFIX's value will be a list at runtime is not
significant, since macros process source code.

MSET should be written as:

(defmacro mset (array indices)
  `(apply #'aref ,array ,indices))

You could also define MSET as a function:

(defun mset (array indices)
  (apply #'aref array indices))

but then you'll have to use DEFSETF to make it work with SETF, or just use
the APPLY form itself in SETF's first subform.

Or you could use the array copier that someone else posted.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Danny Brewer
Subject: Re: ,@ not working
Date: 
Message-ID: <275@farallonfarallon.com>
In article <·····@ector.cs.purdue.edu>, ···@cs.purdue.EDU (Wei Jen Yeh) writes:
> 
> (defun copy_array (array)
>   (let* ((dims (array-dimensions array))
>          (new_array (funcall #'make-array dims)))
>         (copy_array_elmts new_array array NIL dims)
>         new_array))
> 
> (defmacro mset (array indices)
>   `(aref ,array ,@indices))
> 
> (defun copy_array_elmts (new old prefix rest_dims)
>   (if (null rest_dims)
>       (setf (mset new prefix) (mset old prefix))
>       (let ((n (car rest_dims))
>             (i 0))
>            (loop (if (= i n)
>                      (return T))
>                  (copy_array_elmts new old
>                                    (append prefix (list i)) (cdr rest_dims))
>                  (setq i (+ i 1))))))
> 

In the macro mset, the indices param must be a list.  When you call
it with prefix, you get the error because prefix is not a list.
Try making mset a function so that you can pass it a paramater
which will be evaluated into a list, such as your prefix variable.

   (defun mset (array indices)
     (apply #'aref array indices))
   (proclaim '(inline mset))


Here's a function I wrote to copy arrays.  The new array has the
same dimensions and characteristics as the original array.  I was
originally using a DOTIMES or LOOP to copy the elements, but
someone in this newsgroup pointed out (about six months ago?)
that using REPLACE is faster.  Indeed, when I changed my copy
array to use REPLACE it was over twice as fast in copying an
array of 10x10x10x10 of a constant fixnum running on Macintosh
Common Lisp.

(DEFUN Copy-Array (array &KEY copierFn)
  "Return a copy of an array."
  (LET* (
         (arrayType (ARRAY-ELEMENT-TYPE array))
         (arraySize (ARRAY-TOTAL-SIZE array))
         (newArray (MAKE-ARRAY (ARRAY-DIMENSIONS array)
                               :ELEMENT-TYPE arrayType
                               :ADJUSTABLE (ADJUSTABLE-ARRAY-P array)))
         (source (MAKE-ARRAY arraySize
                             :ELEMENT-TYPE arrayType
                             :DISPLACED-TO array))
         (dest (MAKE-ARRAY arraySize
                           :ELEMENT-TYPE arrayType
                           :DISPLACED-TO newArray))
         )
    (IF copierFn
      (DOTIMES (i arraySize)
        (SETF (ELT dest i) (FUNCALL copierFn (ELT source i))))

      ;; If no copierFn was supplied, then use REPLACE
      ;;  because the compiler might generate much more
      ;;  efficient code for it.
      (REPLACE dest source))
    newArray))

If a copierFn is passed in, then the slower DOTIMES is used to
copy the array elements.  A copierFn might be useful for example
if I wanted to do a COPY-SEQ or COPY-TREE or similar operation
on array elements when copying them to the new array so that the
new array elements don't share any structure with the old array.

Danny Brewer
·····@farallon.com
From: Barry Margolin
Subject: Re: ,@ not working
Date: 
Message-ID: <vh94gINNdbi@early-bird.think.com>
In article <···@farallonfarallon.com> ·····@farallon.com (Danny Brewer) writes:
>   (defun mset (array indices)
>     (apply #'aref array indices))
>   (proclaim '(inline mset))

The PROCLAIM should go before the DEFUN.  Many compilers will only retain
the information needed for inline expansion if the function name is
proclaimed INLINE when the definition is being processed.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar