From: Albert Krewinkel
Subject: destructive modifications using iterate
Date: 
Message-ID: <f5s2em$mim$1@registered.motzarella.org>
Hello,

I just hacked together a simple extension for `iterate' to step
through a 2d matrix element wise (code below).  But iteration with
this extension doesn't allow me to destructively modify the matrix.
Therefore my question: It seems to me that I have to provide some
additional macro to get such functionality.  Is that correct, do I
really have to write an additional macro like `with-matrix-elements'?
Or do I miss some important things here, and there is an easy way to
do this with iterate?

A small example to clarify what I mean: I'd like to have

(let ((mat (make-array '(1 2) :initial-contents #((42 65)))))
  (iter (for el in-matrix mat)
        (print el)
        (setf el 5))
  mat)

returning #A((5 5)) instead of #A(42 65).  What is the right way to do
this?

I'm don't know much about `series' yet, but it provides an `alter'
function so it might be an alternative, too.  (Functional style,
though)

Thanks
Albert



(defmacro-driver (FOR var IN-MATRIX matrix &optional BY (row-or-column 'row))
  (let ((mat (gensym "MAT"))
        (kwd (if generate 'generate 'for)))
    (ecase row-or-column
      ('row
       (let ((end (gensym "END-INDEX"))
             (index (gensym "INDEX")))
         `(progn
           ;nlisp (with ,mat = (val ,matrix))
           (with ,mat = ,matrix)
           (with ,end = (array-total-size ,mat))
           (with ,index = -1)
           (,kwd ,var next (progn (incf ,index)
                                  (if (>= ,index ,end) (terminate))
                                  (row-major-aref ,mat ,index))))))
      ((or 'column 'col)
       (let ((num-cols (gensym "COLS"))
             (num-rows (gensym "ROWS"))
             (col-index (gensym "COL-INDEX"))
             (row-index (gensym "ROW-INDEX")))
         `(progn
           (with ,mat = (val ,matrix))
           (with ,num-cols = (array-dimension ,mat 0))
           (with ,num-rows = (array-dimension ,mat 1))
           (with ,row-index = -1)
           (with ,col-index = 0)
           (,kwd ,var next (progn (incf ,row-index)
                                  (when (>= ,row-index ,num-rows)
                                    (incf ,col-index)
                                    (if (>= ,col-index ,num-cols)
                                        (terminate)
                                        (setf ,row-index 0)))
                                  (aref ,mat ,row-index ,col-index)))))))))

From: Chris Dean
Subject: Re: destructive modifications using iterate
Date: 
Message-ID: <1182911074.289880.78480@u2g2000hsc.googlegroups.com>
On Jun 26, 3:03 pm, Albert Krewinkel <·······@KEIN-SPAMnatwiss.uni-
luebeck.de> wrote:
> I just hacked together a simple extension for `iterate' to step
> through a 2d matrix element wise (code below).  But iteration with
> this extension doesn't allow me to destructively modify the matrix.

That's right.  The example given is just changing the value of the
local
looping variable, not the matrix itself.

This is similar to using ITER with a vector.  In the vector case you
could
use the index of the vector to to change an element within the
vector.  That is,
your example is doing the equivalent of:

  (let ((v (vector 'a 'b 'c)))
    (iter (for x :in-vector v)
          (print x)
          (setf x 'new))
    v)
  => #(a b c)

when you want:

  (let ((v (vector 'a 'b 'c)))
    (iter (for x :in-vector v :with-index i)
          (print x)
          (setf (aref v i) 'new))
    v)
  => #(new new new)

So for your problem, one solution would be to write a more complex
ITER driver and add
indexing.  The iter mailing list will probably give better suggestions
if you wish to
pursue this problem.

--
Chris Dean
From: Albert Krewinkel
Subject: Re: destructive modifications using iterate
Date: 
Message-ID: <f5t6f3$fm6$1@registered.motzarella.org>
On Tue, 26 Jun 2007 19:24:34 -0700, Chris Dean wrote:
> So for your problem, one solution would be to write a more complex
> ITER driver and add
> indexing.  The iter mailing list will probably give better suggestions
> if you wish to
> pursue this problem.
>

Thanks for the advice. I should have thought of the mailing list.  I will
relocate the discussion there.

Albert
From: Karol Skocik
Subject: Re: destructive modifications using iterate
Date: 
Message-ID: <1182972439.871579.103050@j4g2000prf.googlegroups.com>
On Jun 27, 10:17 am, Albert Krewinkel <·······@KEIN-SPAMnatwiss.uni-
luebeck.de> wrote:
> On Tue, 26 Jun 2007 19:24:34 -0700, Chris Dean wrote:
> > So for your problem, one solution would be to write a more complex
> > ITER driver and add
> > indexing.  The iter mailing list will probably give better suggestions
> > if you wish to
> > pursue this problem.
>
> Thanks for the advice. I should have thought of the mailing list.  I will
> relocate the discussion there.
>
> Albert

Hi,
  just to note, I think you have a bug in the ecase keys:

(ecase some-variable
  ((or x y z) ...))

means that there are 4 keys, not 3: or, x, y, z. I was bitten recently
with something similar...

Cheers,
  Karol