<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><span class="Apple-style-span" style="font-family: monospace; ">Nice catch. Well, once could use left-scan and right-scan, or they could just fix reductions:</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; ">(defun reductions (function sequence &rest args &key initial-value)</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (let ((l (list (or initial-value (first sequence)))))</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (apply #'reduce</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (lambda (a b)</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (let ((val (funcall function a b)))</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (push val l)</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> val))</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> sequence</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> args)</span><span class="Apple-style-span" style="font-family: monospace; "><br></span><span class="Apple-style-span" style="font-family: monospace; "> (nreverse l)))</span></div><div><font class="Apple-style-span" face="monospace"><br></font></div><div><font class="Apple-style-span" face="monospace">left-scan and right-scan also look reasonable. I'm happy with either the clojure-style function or the haskell-style functions. But, one way or the other, I think this would be a useful addition to alexandria.</font></div><div><font class="Apple-style-span" face="monospace"><br></font></div><div><font class="Apple-style-span" face="monospace">cyrus</font></div><div><font class="Apple-style-span" face="monospace"> <br></font><div><div>On Dec 30, 2010, at 9:13 PM, Michael Weber wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>On Dec 30, 2010, at 02:56 , Cyrus Harmon wrote:<br><blockquote type="cite"><br></blockquote><blockquote type="cite">CL-USER> (reductions #'+ '(1 2 3 4))<br></blockquote><blockquote type="cite">(1 3 6 10)<br></blockquote><br>I find this a bit surprising behavior:<br><br>CL-USER> (reductions #'+ '(1 2 3 4) :initial-value 10)<br>(1 11 13 16 20)<br><br>I would have expected (11 13 16 20) or (10 11 13 16 20).<br><br>Here's a counter-proposal, with a similar interface as MAP:<br><br>CL-USER> (left-scan 'vector #'+ 10 '(1 2 3 4))<br>#(11 13 16 20) ;; (vector (+ 10 1) (+ 11 2) ...)<br>CL-USER> (right-scan 'list #'+ 0 '(1 2 3 4))<br>(4 7 9 10) ;; (list (+ 0 4) (+ 4 3) (+ 7 2) ...)<br>CL-USER> (left-scan1 'vector #'+ '(1 2 3 4))<br>#(3 6 10) ;; (vector (+ 1 2) (+ 3 3) (+ 6 4))<br><br>(defun left-scan (type fn init seq &rest seqs)<br> (flet ((next (&rest args)<br> (setf init (apply fn init args))))<br> (apply #'map type #'next seq seqs)))<br><br>(defun left-scan1 (type fn seq)<br> (if (= 0 (length seq))<br> (coerce '() type)<br> (scanl type fn (elt seq 0) (subseq seq 1))))<br><br>(defun left-scan-into (result fn init &rest seqs)<br> (flet ((next (&rest args)<br> (setf init (apply fn init args))))<br> (apply #'map-into result #'next seqs)))<br><br>(defun right-scan (type fn init seq &rest seqs)<br> (let ((rev-seqs (mapcar #'reverse (list* seq seqs))))<br> (apply #'left-scan type fn init rev-seqs)))<br><br>(defun right-scan1 (type fn seq)<br> (apply #'left-scan1 type fn (reverse seq)))<br><br>etc.<br><br>Obviously under-documented, but the intent should be identifyable.<br><br>-- <br>Cheers,<br>Michael<br><br><br>_______________________________________________<br>alexandria-devel mailing list<br><a href="mailto:alexandria-devel@common-lisp.net">alexandria-devel@common-lisp.net</a><br>http://common-lisp.net/cgi-bin/mailman/listinfo/alexandria-devel<br></div></blockquote></div><br></div></body></html>