I'm trying to wrap my head around Elisp's cl-loop facility but can't seem to find a way to skip elements. Here's an artificial example to illustrate the problem: I'd like to loop over a list of integers and get a new list in which all odd integers from the original list are squared. The even integers should be omitted.
According to the documentation of cl-loop, I should be able to do this:
(loop for i in '(1 2 3)
if (evenp i)
append (list)
else
for x = (* x x)
and append (list x))
The desired output is '(1 9)
instead I get an error:
cl--parse-loop-clause: Expected a `for' preposition, found (list x)
Apparently the and
doesn't work as expected but I don't understand why. (I'm aware that I could simplify the else block to consist of only one clause such that the and
isn't needed anymore. However, I'm interested in situations where you really have to connect several clauses with and
.)
Second part of the question: Ideally, I would be able to write this:
(loop for i in '(1 2 3)
if (evenp i)
continue
for x = (* x x)
append (list x))
Continue is a very common way to skip iterations in other languages. Why doesn't cl-loop have a continue operator? Is there a simple way to skip elements that I overlooked (simpler than what I tried in the first example)?
In Common Lisp it is not possible to write such a LOOP. See the LOOP Syntax.
There is a set of variable clauses on the top. But you can't use one like FOR
later in the main clause. So in an IF
clause you can't use FOR
. If you want to introduce a local variable, then you need to introduce it at the top as a WITH
clause and set it later in the body.
(loop for i in '(1 2 3)
with x
if (evenp i)
append (list)
else
do (setf x (* i i))
and append (list x))
LOOP
in Common Lisp also has no continue
feature. One would use a conditional clause.
Note, that Common Lisp has a more advanced iteration construct as a library ITERATE
. It does not exist for Emacs Lisp, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With