Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lisp: Collect multiple lists in loop

I want to be able to collect multiple lists inside a loop.

I know this can be done without a loop, however I was wondering whether this would be possible with a loop as well. I'd like something like this:

  (loop for var in list
        (if (cond1 var)
            (if (cond2 var)
                collect into list1
                collect into list2))
        finally (list list1 list2))

I get the error that the LOOP keyword is expected, I guess the collect should be used right after a when or a loop. Is there any way to solve that?

like image 391
Kevin Van Ryckegem Avatar asked Dec 11 '22 13:12

Kevin Van Ryckegem


1 Answers

Believe it or not you have too many parentheses. loop has its own little sublanguage which is quite different from Common Lisp s-expressions.

(loop :for var :in list
      :when (cond1 var)
        :if (cond2 var)
           :collect var :into list1
        :else
           :collect var :into list2
        :end
      :end
      :finally (return (list list1 list2)))

In addition I specify what to :collect and :finally just evaluates so you need to use (return ...) or else you can expect nil.

I use keywords for loop keywords to distinguish them from other symbols. It's just style. The indentation is of course ignored and just for readability, but :end isn't. However in this case both :end keywords are redundant since the loop is parsed correctly without them.

I'm by no means a loop wiz.. Every time I get something slightly complex I tend to use Land of Lisp's Periodic table or Loop for black belts, a chapter from Practical Common Lisp.

Periodic table of Loop Macro

like image 148
Sylwester Avatar answered Dec 27 '22 20:12

Sylwester