Subject: Re: Newbie style questions
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 16 Aug 2005 23:19:43 -0500
Newsgroups: comp.lang.lisp
Message-ID: <K4mdnW_8UMFCJ5_eRVn-rA@speakeasy.net>
Dan Schmidt  <dfan@dfan.org> wrote:
+---------------
| batkins57@gmail.com writes:
| | After learning a little more, I've rewritten the code to this:
| | (defun partition (pred list)
| |   (let (in out)
| |     (loop for item in list do
| | 	  (if (funcall pred item)
| | 	      (setf in (cons item in))
| | 	    (setf out (cons item out))))
| |     (values in out)))
| 
| More idiomatic would be
|   (defun partition (pred list)
|     (let (in out)
|       (dolist (item list)
|         (if (funcall pred item)
|             (push item in)
|             (push item out)))
|       (values in out)))
+---------------

Or use the COLLECT...INTO construct in LOOP:

    (defun partition (pred list)
      (loop for item in list
	when (funcall pred item)
	  collect item into in
	else
	  collect item into out
	finally (return (values in out))))

For what it's worth [if anything!], this version preserves the
initial relative ordering of items which pass/don't-pass the
predicate, e.g.:

    > (partition (lambda (x) (zerop (mod x 3))) (iota 30))

    (0 3 6 9 12 15 18 21 24 27)
    (1 2 4 5 7 8 10 11 13 14 16 17 19 20 22 23 25 26 28 29)
    > 

The original [and Dan's] version(s) reversed them:

    > (original-partition (lambda (x) (zerop (mod x 3))) (iota 30))

    (27 24 21 18 15 12 9 6 3 0)
    (29 28 26 25 23 22 20 19 17 16 14 13 11 10 8 7 5 4 2 1)

    > 


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607