[iterate-devel] destructively altering elements

Albert Krewinkel krewink at inb.uni-luebeck.de
Wed Jun 27 12:40:37 UTC 2007


On Wed, Jun 27, 2007 at 12:48:48PM +0200, Hoehle, Joerg-Cyril wrote:
> Albert Krewinkel wrote:
> >(symbol-macrolet ((el (aref vec row-index col-index)))
> >   (... body...))
> Macrolet is a possibility, but what about writing a driver that provides
> access to the 2 index variables, modeled after in-vector?
> (for x in-vector foo with-index i)
> (for e in-matrix foo with-indices (i j))
>   (setf (aref foo i j) bar)

That sure is a good way to do this.  Maybe you are right, and the
python zen "explizit is better than implicit" applies to this
situation as well. But I just feel like it's more verbose than
necessary.

> BTW, how do you use Iterate to walk across a 2-dimensional thing like a
> matrix? This would likely involve 2 nested iterations, so any single
> clause does not provide a complete solution?!?
> 
> Regards,
> 	Jorg Hohle

A single clause is sufficient for my needs, see code below. It's a
quick hack and for testing only, so it's plain ugly.

One of my concernes is efficiency.  It might be premature
optimization, but still: If I do

(let ((v (vector 65 42 23 5 105)))
  (iter (for el in-vector v with-index i)
        (setf (aref v i) 1))
  v)

the expansion code will contain (setq el (aref...)).  Having a
variable to be set to a new value in every iteration, although not
needed, doesn't seem to be optimal.  Of course I could just iterate
using the index, but wouldn't I loose some nice abstractions this
way?

Thanks for your help
Albert


<code style="ugly">

(defmacro-driver (FOR var IN-MATRIX matrix &optional
                      WITH-INDICES (indices (list (gensym "ROW")
                                                  (gensym "COL")))
                      BY (row-or-column 'column))
  (let ((mat (gensym "MAT"))
        (kwd (if generate 'generate 'for)))
    (ecase row-or-column
      ((or column col)
       (let ((num-cols (gensym "COLS"))
             (num-rows (gensym "ROWS"))
             (col-index (car indices))
             (row-index (cadr indices)))
         `(progn
           ;nlisp (with ,mat = (val ,matrix))
           (initially (setq ,col-index 0))
           (with ,mat = ,matrix)
           (with ,num-cols = (array-dimension ,mat 1))
           (with ,num-rows = (array-dimension ,mat 0))
           (with ,row-index = -1)
           (generate ,col-index next (incf ,col-index))
           (,kwd ,var next (progn (incf ,row-index)
                                  (when (>= ,row-index ,num-rows)
                                    (if (>= (next ,col-index) ,num-cols)
                                        (terminate)
                                        (setf ,row-index 0)))
                                  (aref ,mat ,row-index ,col-index))))))
      ('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)))))))))

</code>



More information about the iterate-devel mailing list