Does the cl-loop
macro implement an equivalent to the continue
keyword of other languages?
The behavior of break
can be achieved by using until
or while
clauses by placing them in the middle of cl-loop
, e.g.
(cl-loop item in '(1 2 3 4)
do (print item)
until (= 3 item)
do (print item))
will be roughly equivalent to Python code
for item in [1, 2, 3, 4]:
print(item)
if item == 3:
break
print(item)
However, I cannot identify any clause, that says "abort this iteration step, continue with the next", like the continue
keyword would do. Is there such a clause?
Usage example
Let's say I want to do something for every string in a list. From the string I want to derive a file-name, and if it exists, collect data about those files.
With a continue
clause:
(defconst mylist '(1 2 "hello" 3 "world" 4))
(defconst mylist-file-data
(cl-loop for prefix in mylist
unless (stringp prefix) continue
for file-name = (concat prefix ".txt")
unless (file-exists-p file-name) continue
for attributes = (file-attributes file-name)
for mtime = (file-attribute-modification-time attributes)
for size = (file-attribute-size attributes)
collect (list file-name mtime size)))
By contrast, without a continue
clause I cannot use for
clauses to define variables, that can only be defined when the condition is fulfilled. Instead I need to reformulate the loop more awkwardly, e.g. as
(defconst mylist-file-data
(cl-loop for prefix in mylist
for file-name = (if (stringp prefix) (concat prefix ".txt"))
for attributes = (if (file-exists-p file-name) (file-attributes file-name))
for mtime = (if attributes (file-attribute-modification-time attributes))
for size = (if attributes (file-attribute-size attributes))
if attributes
collect (list file-name mtime size)))
Note how all (if ...)
s are executed for each iteration step, even when the first already decides that the step could be skipped.