Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

loop iterate and nested collection

97 views
Skip to first unread message

Francogrex

unread,
Mar 3, 2011, 5:29:54 AM3/3/11
to
Consider this:

(loop for i from 1 to 5 do
(loop for j in '("a" "b" "c" "d")
collect (list i j)))
> NIL

In the package iterate to avoid that the list created by the inner
iterate is simply ignored by the outer one, they propose this elegant
solution below:

(in-package :iterate)

(iter outer (for i from 1 to 5)
(iter inner (for j in '("a" "b" "c" "d"))
(in outer (collect (list i j)))))

> ((1 "a") (1 "b") (1 "c") (1 "d") (2 "a") (2 "b") (2 "c") (2 "d") (3 "a")
(3 "b") (3 "c") (3 "d") (4 "a") (4 "b") (4 "c") (4 "d") (5 "a") (5
"b")
(5 "c") (5 "d"))

One can come up with a workaround for loop such as:

(let ((storage nil))
(loop for i from 1 to 5 do
(loop for j in '("a" "b" "c" "d") do
(push (list i j) storage)))
(nreverse storage))

> ((1 "a") (1 "b") (1 "c") (1 "d") (2 "a") (2 "b") (2 "c") (2 "d") (3 "a")
(3 "b") (3 "c") (3 "d") (4 "a") (4 "b") (4 "c") (4 "d") (5 "a") (5
"b")
(5 "c") (5 "d"))

But I wonder if there is a more 'elegant' solution for loop that is
similar to the one used by iterate?

Peder O. Klingenberg

unread,
Mar 3, 2011, 5:37:51 AM3/3/11
to
Francogrex <fra...@grex.org> writes:

> But I wonder if there is a more 'elegant' solution for loop that is
> similar to the one used by iterate?

Change "do" to "append" in the outer loop:

(loop for i from 1 to 5 append


(loop for j in '("a" "b" "c" "d")
collect (list i j)))

> ((1 "a") (1 "b") (1 "c") (1 "d") (2 "a") (2 "b") (2 "c") (2 "d") (3 "a") (3 "b") (3 "c") (3 "d") (4 "a") (4 "b") (4 "c") (4 "d") (5 "a") (5 "b") (5 "c") (5 "d"))


...Peder...
--
This must be Thursday. I never could get the hang of Thursdays.

serge

unread,
Mar 3, 2011, 5:37:50 AM3/3/11
to
maybe this ?

CL-USER> (loop for i from 1 to 5 append


(loop for j in '("a" "b" "c" "d")
collect (list i j)))

WJ

unread,
Mar 3, 2011, 8:16:01 AM3/3/11
to
Francogrex wrote:

Don't use LOOP. Only COBOL programmers like LOOP.


Scheme:

(define (curry f . args) (lambda x (apply f (append args x))))

(append-map
(lambda (i) (map (curry list i) '("a" "b" "c")))
(iota 5 1 1))

((1 "a") (1 "b") (1 "c") (2 "a") (2 "b") (2 "c")
(3 "a") (3 "b") (3 "c") (4 "a") (4 "b") (4 "c")
(5 "a") (5 "b") (5 "c"))

Frode V. Fjeld

unread,
Mar 3, 2011, 8:24:21 AM3/3/11
to
"WJ" <w_a_...@yahoo.com> writes:

> Don't use LOOP. [...] Scheme:

I think what you meant to say was, "Don't use Common Lisp".

> Only COBOL programmers like LOOP.

No, only Scheme programmers don't like LOOP.

--
Frode V. Fjeld

Tim Bradshaw

unread,
Mar 3, 2011, 8:29:29 AM3/3/11
to
On 2011-03-03 13:24:21 +0000, Frode V. Fjeld said:

> I think what you meant to say was, "Don't use Common Lisp".

I think what he's been saying for the last few months is "I've really
had a big tantrum about Common Lisp and I am going to stand on my
street corner with my placard, smelling of stale sweat and piss,
ranting incoherently at anyone who will listen".

WJ

unread,
Mar 3, 2011, 10:19:05 AM3/3/11
to
WJ wrote:

MatzLisp (Ruby):

(1..5).map{|i| ("a".."f").map{|c| [i,c]}}.flatten(1)

[[1, "a"],
[1, "b"],
[1, "c"],
[1, "d"],
[1, "e"],
[1, "f"],
[2, "a"],
[2, "b"],
[2, "c"],
[2, "d"],
[2, "e"],
[2, "f"],
[3, "a"],
[3, "b"],
[3, "c"],
[3, "d"],
[3, "e"],
[3, "f"],
[4, "a"],
[4, "b"],
[4, "c"],
[4, "d"],
[4, "e"],
[4, "f"],
[5, "a"],
[5, "b"],
[5, "c"],
[5, "d"],
[5, "e"],
[5, "f"]]

Peter Keller

unread,
Mar 3, 2011, 2:45:19 PM3/3/11
to
WJ <w_a_...@yahoo.com> wrote:
> MatzLisp (Ruby):
>
> (1..5).map{|i| ("a".."f").map{|c| [i,c]}}.flatten(1)

I think the creator of ruby's big joke on the world was that he
convinced people that they really *did* want to write in M-expressions
with APL right-to-left association semantics.

Suddenly, the evil vision of Ruby seems so clear to me....

-pete

jos...@lisp.de

unread,
Mar 3, 2011, 2:55:29 PM3/3/11
to

Common Lisp:

(defun circ (list)
(let ((l (copy-list list)))
(setf (cdr (last l)) l)
l))

$ (mapcan (lambda (i)
(mapcar 'list (circ (list i)) '(a b c)))
(iota 5 1))
((1 A) (1 B) (1 C) (2 A) (2 B) (2 C) (3 A)
(3 B) (3 C) (4 A) (4 B) (4 C) (5 A) (5 B) (5 C))

Rainer Joswig

unread,
Mar 3, 2011, 6:27:48 PM3/3/11
to

$ (mapcan (lambda (i)
(mapcar 'list (circ i) (iota 3 'a)))

Rainer Joswig

unread,
Mar 3, 2011, 6:39:31 PM3/3/11
to

using Common Lisp and CROSS-PRODUCT from Peter Norvig:

$ (cross-product 'list (iota 5 1) (iota 3 'a))
((1 A) (2 A) (3 A) (4 A) (5 A) (1 B) (2 B)
(3 B) (4 B) (5 B) (1 C) (2 C) (3 C) (4 C) (5 C))

Marco Antoniotti

unread,
Mar 4, 2011, 12:24:59 AM3/4/11
to

A nit. The beauty of all the examples we are fooling around with, is
that the are not this or this other person's property. CROSS-PRODUCT
is actually a just-above-the-ground primitive, like IOTA, CURRY,
COMPOSE etc. etc. That is to say, that you should have just said:
"using Common Lisp and CROSS-PRODUCT". (LOOP, OTOH is slightly higher
up from the ground :) ). This is not to diminish Peter Norvig's
contributions of course.

Cheers
--
Marco

Thomas A. Russ

unread,
Mar 4, 2011, 2:27:38 AM3/4/11
to
Francogrex <fra...@grex.org> writes:

> Consider this:
>
> (loop for i from 1 to 5 do
> (loop for j in '("a" "b" "c" "d")
> collect (list i j)))
> > NIL

...


> But I wonder if there is a more 'elegant' solution for loop that is
> similar to the one used by iterate?

(loop for i from 1 to 5
nconc (loop for j in '("a" "b" "c" "d")
collect (list i j)))

NCONC is safe because the list structure generated by the inner collect
is fresh.

--
Thomas A. Russ, USC/Information Sciences Institute

Rainer Joswig

unread,
Mar 4, 2011, 4:50:31 AM3/4/11
to

I just wanted to mention where I took its definition from.
That's a hot topic in Germany right now. Witness
the fate of the last defense minister... ;-)

>
> Cheers
> --
> Marco

WJ

unread,
May 5, 2011, 5:33:54 AM5/5/11
to
WJ wrote:

Arc:

arc> (mappend (fn (i) (map [list i _] '(a b c)))
> '(1 2 3 4 5))
((1 a) (1 b) (1 c) (2 a) (2 b) (2 c) (3 a) (3 b) (3 c)
(4 a) (4 b) (4 c) (5 a) (5 b) (5 c))

--

0 new messages