From: Tamas K Papp on 9 Dec 2009 08:53 On Wed, 09 Dec 2009 04:10:20 -0800, vippstar wrote: > On Dec 9, 1:49 pm, Pascal Costanza <p...(a)p-cos.net> wrote: >> On 09/12/2009 12:19, Tamas K Papp wrote: >> >> > Is there a more idiomatic way to implement this function: >> >> > (defun flatten1 (list) >> > (apply #'concatenate 'list list)) >> >> (apply #'append lists) >> (apply #'nconc lists) >> (loop for list in lists append list) >> (loop for list in lists nconc list) > > (mapcan #'identity list) Thanks! The original application was (setf ,@(flatten1 (mapcar ... so I guess that I can just use (setf ,@(mapcan ... and I don't even need flatten1 after all :-) Tamas
From: Pascal Costanza on 9 Dec 2009 09:15 On 09/12/2009 14:53, Tamas K Papp wrote: > On Wed, 09 Dec 2009 04:10:20 -0800, vippstar wrote: > >> On Dec 9, 1:49 pm, Pascal Costanza<p...(a)p-cos.net> wrote: >>> On 09/12/2009 12:19, Tamas K Papp wrote: >>> >>>> Is there a more idiomatic way to implement this function: >>> >>>> (defun flatten1 (list) >>>> (apply #'concatenate 'list list)) >>> >>> (apply #'append lists) >>> (apply #'nconc lists) >>> (loop for list in lists append list) >>> (loop for list in lists nconc list) >> >> (mapcan #'identity list) > > Thanks! The original application was > > (setf ,@(flatten1 (mapcar ... > > so I guess that I can just use > > (setf ,@(mapcan ... > > and I don't even need flatten1 after all :-) Be careful: mapcan is a destructive operation, so you should also use it if you are sure that the lists are freshly created, and/or not used by any other part of the program. If you are not sure about it, it's better to use the LOOP/APPEND idiom, or look for mapappend, which you can sometimes find defined as a utility function. Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rainer Joswig on 9 Dec 2009 09:17 In article <7o9oejF3oaasdU1(a)mid.individual.net>, Tamas K Papp <tkpapp(a)gmail.com> wrote: > On Wed, 09 Dec 2009 04:10:20 -0800, vippstar wrote: > > > On Dec 9, 1:49 pm, Pascal Costanza <p...(a)p-cos.net> wrote: > >> On 09/12/2009 12:19, Tamas K Papp wrote: > >> > >> > Is there a more idiomatic way to implement this function: > >> > >> > (defun flatten1 (list) > >> > (apply #'concatenate 'list list)) > >> > >> (apply #'append lists) > >> (apply #'nconc lists) > >> (loop for list in lists append list) > >> (loop for list in lists nconc list) > > > > (mapcan #'identity list) > > Thanks! The original application was > > (setf ,@(flatten1 (mapcar ... > > so I guess that I can just use > > (setf ,@(mapcan ... > > and I don't even need flatten1 after all :-) > > Tamas CL-USER 2 > (let ((l1 (copy-tree '((a 1) (b 2) (c 3))))) (values (mapcan #'identity l1) l1)) (A 1 B 2 C 3) ((A 1 B 2 C 3) (B 2 C 3) (C 3)) MAPCAN is destructively modifying the original (sub)list(s) (using NCONC). That means: 1) the lists that are NCONCed should not be literal lists. 2) the original list gets modified, if you don't like that, you need to copy the right cons cells first. COPY-LIST is not enough, since that copies only the first level cons cells. -- http://lispm.dyndns.org/
From: Tamas K Papp on 9 Dec 2009 09:22 On Wed, 09 Dec 2009 15:15:54 +0100, Pascal Costanza wrote: > On 09/12/2009 14:53, Tamas K Papp wrote: >> On Wed, 09 Dec 2009 04:10:20 -0800, vippstar wrote: >> >>> On Dec 9, 1:49 pm, Pascal Costanza<p...(a)p-cos.net> wrote: >>>> On 09/12/2009 12:19, Tamas K Papp wrote: >>>> >>>>> Is there a more idiomatic way to implement this function: >>>> >>>>> (defun flatten1 (list) >>>>> (apply #'concatenate 'list list)) >>>> >>>> (apply #'append lists) >>>> (apply #'nconc lists) >>>> (loop for list in lists append list) >>>> (loop for list in lists nconc list) >>> >>> (mapcan #'identity list) >> >> Thanks! The original application was >> >> (setf ,@(flatten1 (mapcar ... >> >> so I guess that I can just use >> >> (setf ,@(mapcan ... >> >> and I don't even need flatten1 after all :-) > > Be careful: mapcan is a destructive operation, so you should also use it > if you are sure that the lists are freshly created, and/or not used by > any other part of the program. If you are not sure about it, it's better > to use the LOOP/APPEND idiom, or look for mapappend, which you can > sometimes find defined as a utility function. I am using backquote to construct the lists. The spec says that "The constructed copy of the template might or might not share list structure with the template itself.", so I am wondering. My examples look like this: (setf ,@(mapcan (lambda (size) `((mem-ref ,size :int32) -1)) sizes)) (setf ,@(mapcan (lambda (returned-size pointer lla-type size) `(,returned-size (floor (mem-aref* ,pointer ,lla-type)) (mem-ref ,size :int32) ,returned-size)) returned-sizes pointers lla-types sizes)) I would reason that this is safe since all lists are constructed from atoms, so they cannot share structure. But is (mapcan (lambda () `(...))) safe in general? Thanks, Tamas
From: Frode V. Fjeld on 9 Dec 2009 09:29 Rainer Joswig <joswig(a)lisp.de> writes: > > CL-USER 2 > (let ((l1 (copy-tree '((a 1) (b 2) (c 3))))) > (values (mapcan #'identity l1) > [..] > > COPY-LIST is not enough, since that copies only > the first level cons cells. Shouldn't (mapcan #'copy-list l1) do the trick? -- Frode V. Fjeld
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: complex symmetric matrices Next: Parallel programming in CL? |