# (lispkit iterate)

Library `(lispkit iterate)` defines syntactical forms supporting frequently used iteration patterns. Some of the special forms were inspired by Common Lisp.

**(dotimes (*****var count*****)&#x20;*****body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(dotimes (*****var count result*****)&#x20;*****body ...*****)**

`dotimes` iterates variable *var* over the integer range *\[0, count\[*, executing *body* for every iteration.

`dotimes` first evaluates *count*, which has to evaluate to a fixnum. If *count* evaluates to zero or a negative number, *body ...* is not executed. `dotimes` then executes *body ...* once for each integer from 0 up to, but not including, the value of *count*, with *var* bound to each integer. Then, *result* is evaluated and its value is returned as the value of the `dotimes` form. If *result* is not provided, no value is being returned.

```scheme
(let ((res 0))
  (dotimes (i 10 res)
    (set! res (+ res i))))  ⟹  45
```

**(dolist (*****var lst*****)&#x20;*****body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(dolist (*****var lst result*****)&#x20;*****body ...*****)**

`dolist` iterates variable *var* over the elements of list *lst*, executing *body ...* for every iteration.

`dolist` first evaluates *lst*, which has to evaluate to a list. It then executes *body ...* once for each element in the list, with *var* bound to the current element of the list. Then, *result* is evaluated and its value is returned as the value of the `dolist` form. If *result* is not provided, no value is being returned.

```scheme
(let ((res ""))
  (dolist (x '("a" "b" "c") res)
    (set! res (string-append res x))))  ⟹  "abc"
```

**(loop&#x20;*****break body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">

`loop` iterates infinitely, executing *body ...* in each iteration. *break* is a variable bound to an exit function which can be used to leave the `loop` form. *break* receives one argument which is the result of the `loop` form.

```scheme
(let ((i 1))
  (loop break
    (if (> i 100)
        (break i)
        (set! i (* i 2)))))  ⟹  128
```

**(while&#x20;*****condition body ...*****)**   <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(while&#x20;*****condition*****&#x20;unless&#x20;*****break body ...*****)**

`while` iterates as long as *condition* evaluates to a value other than `#f`, executing *body ...* in each iteration. `unless` can be used to bind an exit funtion to variable *break* so that it is possible to leave the loop by calling thunk *break*. `while` forms never return a result.

```scheme
(let ((i 0)(sum 0))
  (while (< sum 100) unless exit
    (if (> i 10) (exit))
    (set! sum (+ sum i))
    (set! i (fx1+ i)))
  (cons i sum))  ⟹  (11 . 55)
```

**(for&#x20;*****var*****&#x20;from&#x20;*****lo*****&#x20;to&#x20;*****hi body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(for&#x20;*****var*****&#x20;from&#x20;*****lo*****&#x20;to&#x20;*****hi*****&#x20;step&#x20;*****s body ...*****)**

This form of `for` iterates through all the fixnums from *lo* to *hi* (both inclusive), executing *body ...* in each iteration. If step *s* is provided, *s* is used as the increment of variable *var* which iterates through the elements of the given range.

When this `for` form is being executed, first *lo* and *hi* are evaluated. Both have to evaluate to a fixnum. Then, *body ...* is executed once for each integer in the given range, with *var* bound to the current integer. The form returns no result.

```scheme
(let ((res '()))
  (for x from 1 to 16 step 2
    (set! res (cons x res)))
  res)  ⟹  (15 13 11 9 7 5 3 1)
```

**(for&#x20;*****var*****&#x20;in&#x20;*****lst body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(for&#x20;*****var*****&#x20;in&#x20;*****lst*****&#x20;where&#x20;*****condition body ...*****)**\
\&#xNAN;**(for&#x20;*****var*****&#x20;from&#x20;*****(x ...) body ...*****)**

This form of `for` iterates through all the elements of a list, executing *body ...* in each iteration. The list is either explicitly given via *lst* or its elements are enumerated in the form *(x ...)*. If a *where* predicate is provided, the it acts as a filter on the elements through which variable *var* is iterated.

When this `for` form is being executed, first *lst* or *(x ...)* is evaluated. Then, *body ...* is executed once for each element in the list, with *var* bound to the current element of the list. The form returns no result.

```scheme
(let ((res '()))
  (for x in (iota 16) where (odd? x)
    (set! res (cons x res)))
  res)  ⟹  (15 13 11 9 7 5 3 1)
```

**(exit-with&#x20;*****break body ...*****)** <img src="/files/gEcsZuRGyhWFw4tM60U7" alt="" data-size="line">\
\&#xNAN;**(exit-with&#x20;*****break*****&#x20;from&#x20;*****body ...*****)**

`exit-with` is not an iteration construct by itself. It is often used in combination with iteration constructs to declare an exit function for leaving statements *body ...*. *break* is a variable which gets bound to the exit function in the scope of statements *body ...*. `exit-with` either returns the result of the last statement of *body ...* or it returns the value passed to *break* in case the exit function gets called.

```scheme
(exit-with break
  (display "hello")
  (break #f)
  (display "world"))  ⟹  #f  ; printing "hello"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.lisppad.app/libraries/lispkit/lispkit-iterate.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
