[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
NMAP
(defun nmap (result-sequence function &rest sequences)
(let ((length (length result-sequence))
(arguments (make-list (length sequences)))
(rs result-sequence)
result-element)
(dolist (sequence sequences)
(setq length (min length (length sequence))))
(dotimes (index length)
(do* ((args arguments (cdr args))
(seqs sequences (cdr seqs))
(sequence (car sequences) (car seqs)))
((null args))
(setf (car args)
(cond ((listp sequence)
(setf (car seqs) (cdr sequence))
(car sequence))
(t
(aref sequence index)))))
(setq result-element (apply function arguments))
(cond ((listp result-sequence)
(setf (car rs) result-element)
(setq rs (cdr rs)))
(t
(setf (aref result-sequence index) result-element))))
result-sequence))
I have pursued this simply because I have found nmap to be quite
useful. For example, to fill a sequence with random numbers, one can
use (nmap sequence #'(lambda () (random 1.0))). (This also illustrates
that nmap may take zero additional sequence arguments.) I'd like to
encourage Symbolics, TI, et al. to add this as an extension.
Note that nmap is a function rather than a macro. This is surely
the right thing.
I was able to reduce the consing only down to M cells, where M is
the number of additional sequences passed, while still remaining within
Common Lisp. Lisp machines can reduce it to zero.
Probably this code can be improved in other ways, but it is
competitive with map on the Explorer. (Our Symbolics crashed earlier
today).
Caveat emptor: I only just wrote this version, so there could
*conceivably* be a bug or two, although I tested it. I also had to type
it in by hand on a Mac.
(Incidentally, Scott, I found it far from trivial to come up with
a macro that correctly implements nmap with no consing. In fact, after
a while I decided to give up on it. If you decide to do it for fun,
I'd like to see the result.)
Bob Sasseen
veracsd.rs@a.isi.edu (arpanet)