[alexandria-devel] reductions
Michael Weber
michaelw+alexandria at foldr.org
Fri Dec 31 04:13:42 UTC 2010
On Dec 30, 2010, at 02:56 , Cyrus Harmon wrote:
>
> CL-USER> (reductions #'+ '(1 2 3 4))
> (1 3 6 10)
I find this a bit surprising behavior:
CL-USER> (reductions #'+ '(1 2 3 4) :initial-value 10)
(1 11 13 16 20)
I would have expected (11 13 16 20) or (10 11 13 16 20).
Here's a counter-proposal, with a similar interface as MAP:
CL-USER> (left-scan 'vector #'+ 10 '(1 2 3 4))
#(11 13 16 20) ;; (vector (+ 10 1) (+ 11 2) ...)
CL-USER> (right-scan 'list #'+ 0 '(1 2 3 4))
(4 7 9 10) ;; (list (+ 0 4) (+ 4 3) (+ 7 2) ...)
CL-USER> (left-scan1 'vector #'+ '(1 2 3 4))
#(3 6 10) ;; (vector (+ 1 2) (+ 3 3) (+ 6 4))
(defun left-scan (type fn init seq &rest seqs)
(flet ((next (&rest args)
(setf init (apply fn init args))))
(apply #'map type #'next seq seqs)))
(defun left-scan1 (type fn seq)
(if (= 0 (length seq))
(coerce '() type)
(scanl type fn (elt seq 0) (subseq seq 1))))
(defun left-scan-into (result fn init &rest seqs)
(flet ((next (&rest args)
(setf init (apply fn init args))))
(apply #'map-into result #'next seqs)))
(defun right-scan (type fn init seq &rest seqs)
(let ((rev-seqs (mapcar #'reverse (list* seq seqs))))
(apply #'left-scan type fn init rev-seqs)))
(defun right-scan1 (type fn seq)
(apply #'left-scan1 type fn (reverse seq)))
etc.
Obviously under-documented, but the intent should be identifyable.
--
Cheers,
Michael
More information about the alexandria-devel
mailing list