do

The usage of do looks irrationally complex but in fact it is almost identical to C’s for statement.

In C you might say:

for (i=1,j=20; i<10; i++,j*=2) {
  ...
}

where you are describing:

  • a number of initialisation statements, i=1 and j=2

  • a conditional expression to continue the loop, i<10

  • instructions on how to update the loop variables, i++ and j*=2

  • a loop body, ...

You don’t need to initialise anything. You don’t need to update anything. You are only required to have a loop conditional expression and a body (also known as while).

We don’t have C’s post-increment or self-multiply operators in Idio so we’ll have to express those “long-hand” but the do loop will look remarkably similar.

Let’s break do’s syntax down, first: do var-clauses test-result body.

Here, each var-clause in the list var-clauses looks like: (var init step) where we declare the name of the variable, have an expression to initialize it and step, an expression to generate a new value for the next iteration of the loop.

For our two variables from C, the two var-clauses look like:

(i 1  (i + 1))

(j 20 (j * 2))

and so, together, in a list look like:

((i 1  (i + 1))
 (j 20 (j * 2)))

The test-result list is a bit more interesting than C in that not only do we have a conditional test for continuing the loop but we can also define an expression for the value to return from do. C doesn’t return a value from for so this may be something new.

If you don’t want to return a value, you still need to put something in that slot, say, #n.

So the test-result for us should look like ((i lt 10) #n) although we could have returned whatever was appropriate, potentially using the loop variables, say, (i - j) – or perhaps something less predictable.

(do ((i 1  (i + 1))
     (j 20 (j * 2)))
    ((i lt 10)
     #n)
    {
      ...
    })

In summary, do looks messier (lists of lists) but is functionally identical to C’s for statement.

Note

This example puts parenthesis around the whole do expression. That doesn’t change the way it is interpreted, any expression with multiple elements is treated as a list by the reader.

Here, it probably helps your $EDITOR indent the text properly with the clauses on separate lines!

*

As with C, you don’t need to use any loop variables although you do need to pass an empty list, #n, in place of the var-clauses list.

That means the previous do loop degenerates to:

(do #n
    ((i lt 10)
     #n)
    {
      ...
    })

Here, the variable i being tested in the conditional expression will now be searched for in an outer scope, just like in C. If it doesn’t exist you’ll get an error. If it’s not the i you were looking for then the unexpected might happen.

Last built at 2026-01-04T22:40:02Z+0000 from da47fd3 (dev)