Name

loop

Usage

macro

Syntax

(loop &body forms)

Description

Creates a loop. The loop macro is based on the Common Lisp iterate macro by Jonathan Amsterdam.

Elements of a loop

A loop consists of top-level clauses that drive the loop, such as for and generate, clauses that may appear at deeper levels than the top level, such as break, and ordinary Kiezellisp forms.

Loop driver variables are declared 'outside' the loop and should not be bound directly to lambda definitions within the loop.

The value of a loop expression is (in this order):

Neverending loop

(loop
     (print-line "Hello, world"))

user > (macroexpand '(loop (print-line "Hello, world")))
it: (do
        (label test-label)
        (do
            (do
                (print-line "Hello, world"))
            (goto test-label)))

Loop with a counter

user > (loop (with i initially 2 then (inc i)) (finish-if (= i 5)) (print-line i))
2
3
4
it: null

Loop with a range

user > (loop (for i in (range 2 5)) (print-line i))
2
3
4
it: null
user > (loop (for i from 2 below 5) (print-line i))
2
3
4
it: null

Loop over a list

user > (loop (for i in-list '(a b c d e) by cddr) (print-line i))
a
c
e
it: null
user > (loop (for i on-list '(a b c d e) by cddr) (print-line i))
a b c d e
c d e
e
it: null

Generate and next clauses

user > (loop (for x in '(a b null c))
             (generate i from 1)
             (if x (collecting (list x (next i)))))
it: ((a 1) (b 2) (c 3))

Loop with an explicit return value

user > (loop (for x in '(a b c d))
           (break-if (= x 'b) 123))
it: 123

Loop with an unnamed accumulated value

user > (loop (for x in (series 1 50))
           (summing x))
it: 1275

Loop with a named accumulated value

user > (loop (for x in (series 1 50))
           (summing x into the-sum)
           (multiplying x into the-product)
           (finally
               (list the-sum the-product)))
it: (1275 30414093201713378043612608166064768844377641568960512000000000000)

Toplevel loop clauses

(initially form*)
(finally form*)
(with sym initially expr1 then expr2)
(for expr times)
(for sym from expr1 to expr2 by expr3)
(for sym from expr1 to expr2)
(for sym from expr1 downto expr2)
(for sym from expr1 above expr2)
(for sym from expr1 below expr2)
(for sym from expr1)
(for sym in seq)
(for sym in-list lst by sym2)
(for sym in-list lst)
(for sym on-list lst by sym2)
(for sym on-list lst)
(generate expr times)
(generate sym from expr1 to expr2 by expr3)
(generate sym from expr1 to expr2)
(generate sym from expr1 downto expr2)
(generate sym from expr1 above expr2)
(generate sym from expr1 below expr2)
(generate sym from expr1)
(generate sym in seq)
(generate sym in-list lst by sym2)
(generate sym in-list lst)
(generate sym on-list lst by sym2)
(generate sym on-list lst)

Other loop clauses

(next sym)
(collecting expr into sym)
(collecting expr)
(counting expr into sym)
(counting expr)
(summing expr into sym)
(summing expr)
(multiplying expr into sym)
(multiplying expr)
(maximizing expr into sym)
(maximizing expr)
(minimizing expr into sym)
(minimizing expr)