[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