David Wallis wrote:
> Hello,
> I have just started to learn lisp, and I'm struggling to understand
> how and when lists are/can be evaluated. I want to add some functions to
> implement array syntax (e.g. like IDL/Matlab) on arithmetic expressions,
> e.g.
> (.exp (.* alpha i 2 pi))
> where .exp and .* are array operators, and alpha is an n-dimensional
> array.
>
> The guts of the method is a loop
> (dotimes (i (array-total-size a))
> (setf (row-major-aref r i) (* (row-major-aref (svref v 0) i) 2 pi)))
> [v is a vector holding my arguments]
>
> This works fine.
> However, I have a function that will generate, from a list of arguments,
> an arithmetic expression that has either (row-major-aref (svref v n) i)
> for array arguments, or just the argument for scalers, so I can mix them
> freely. I now want to be able to do something like the following:
> (setf f '(* (row-major-aref (svref v 0) i) 2 pi)) ; my arithmetic
> expression
> (dotimes (i (array-total-size a)) ; Iterate over the array
> with my expression
> (setf (row-major-aref r i) f))
>
> BUT: I can't figure out how to make lisp fill my array r with the
> result of evaluating f, rather than f itself, [I get an array full of
> the list (* (row-major-aref (svref v 0) i) 2 pi) ]
> How do I go about doing this ?
Well, you could use eval on f...
Don't, though. Really. Never, ever use eval, unless you have no other option
whatsoever.
What you *should* do is put a function in f and call that, somewhat like
this:
(setf f (lambda (v i) (* (row-major-aref (svref v 0) i) 2 pi))
(dotimes (i (array-total-size a))
(setf (row-major-aref r i) (funcall f v i)))
Munge as needed, and read up on anonymous (lambda) functions and closures.