(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?
> 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.
CL-USER> (loop for i from 1 to 5 append
(loop for j in '("a" "b" "c" "d")
collect (list i j)))
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"))
> 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
> 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".
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"]]
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
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))
$ (mapcan (lambda (i)
(mapcar 'list (circ i) (iota 3 'a)))
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))
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
> 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
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
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))
--