019
019

Reputation: 480

Collect AND do something under a condition inside a Common Lisp loop

I need to execute an instruction in addition of "collect" under a condition in a loop and I can't figure out a working syntax...

For instance I'd like the following code to print i and collect it whenever 2 < i.

(loop for i '(1 2 3 4) in  when (< 2 i) (print i) collect i)  ==> (3 4)

Hoping you can help !

Upvotes: 2

Views: 1933

Answers (3)

coredump
coredump

Reputation: 38799

In your case it would be shorter to use the return value of print:

(loop for i in '(1 2 3 4) when (> i 2) collect (print i))

Upvotes: 1

Sylwester
Sylwester

Reputation: 48745

Multiple clauses in :if or :when needs to be joined by :and. The keyword :end actually is ignored and does nothing else than make you feel more at ease reading it.

(loop :for i :in '(1 2 3 4)
      :when (< 2 i) 
        :do (print i) 
        :and :collect i
      :end)  ; ==> (3 4) (and prints 3 and 4 as side effect)

I suggest you read LOOP for Black Belts. If you look right above this part you'll see :and in a slightly more complex example.

NB: loop accepts symbols from any package so my style is to use the keyword package not to pollute my own package with loop keywords and my editor highlights it slightly better. You don't need to do it my way :-)

Upvotes: 6

Rainer Joswig
Rainer Joswig

Reputation: 139251

CL-USER 71 > (loop for i in '(1 2 3 4)
                   when (> i 2)
                     do (print i) and collect i)

3        ; printed
4        ; printed
(3 4)    ; return value

Upvotes: 4

Related Questions