From: Erik Eilerts
Subject: Style Question
Date: 
Message-ID: <lndmucINNfei@agave.cs.utexas.edu>
       I was wondering which of the following program segments is better: 


       (let ((result nil))
         (mapcar #'(lambda (x)
                    (dolist (y (get-list-of-objects-for x))
                      (push y result)))
                 some-list)
         result)

       
        (mapcan #'(lambda (x)
                    (copy-list (get-list-of-objects-for x)))
                some-list)


        where get-list-of-objects-for returns some list of objects.  The 
results of the function should be a list of these objects joined together,
such that their top-level pointers have all been copied.
 

       Thanks,

          Erik Eilerts
          University of Texas at Austin
From: Mark Kantrowitz
Subject: Re: Style Question
Date: 
Message-ID: <C2605t.3nE.1@cs.cmu.edu>
In article <············@agave.cs.utexas.edu> ·······@cs.utexas.edu (Erik Eilerts) writes:
>       I was wondering which of the following program segments is better: 
>       (let ((result nil))
>         (mapcar #'(lambda (x)
>                    (dolist (y (get-list-of-objects-for x))
>                      (push y result)))
>                 some-list)
>         result)
>
>        (mapcan #'(lambda (x)
>                    (copy-list (get-list-of-objects-for x)))
>                some-list)

Well, first one should use MAPC, not MAPCAR, in the first example, to
avoid wasting cons cells.  Both examples should be equally efficient,
after you do the MAPC/MAPCAR swap.

Secondly, the values returned by the two examples are different, if
order of the elements in the lists is important. 

I prefer the second example because it is a standard Lisp idiom (using
a function with MAPCAN to "filter" a list). The first is just a bunch
of Lisp code used to compute a value, and so lacks the crisp
recognition afforded by the idiomatic nature of the second.

--mark