For loops

FriCAS provide the for and in keywords in repeat loops, allowing you to integrate across all elements of a list, or to have a variable take on integral values from a lower bound to an upper bound. We shall refer to these modifying clauses of repeat loops as for clauses. These clauses can be present in addition to while clauses (See )help while). As with all other types of repeat loops, leave (see )help leave) can be used to prematurely terminate evaluation of the loop.

The syntax for a simple loop using for is

for iterator repeat loopbody

The iterator has several forms. Each form has an end test which is evaluted before loopbody is evaluated. A for loop terminates immediately when the end test succeeds (evaluates to true) or when a leave or return expression is evaluated in loopbody. The value returned by the loop is the unique value of Void.

for i in n..m repeat

If for is followed by a variable name, the in keyword and then an integer segment of the form n..m, the end test for this loop is the predicate i > m. The body of the loop is evaluated m-n+1 times if this number is greater than 0. If this number is less than or equal to 0, the loop body is not evaluated at all.

The variable i has the value n, n+1, ..., m for successive iterations of the loop body. The loop variable is a local variable within the loop body. Its value is not available outside the loop body and its value and type within the loop body completely mask any outer definition of a variable with the same name.

for i in 10..12 repeat output(i**3)
 1000
 1331
 1728
                    Type: Void

The loop prints the values of 10^3, 11^3, and 12^3.

a := [1,2,3]
 [1,2,3]
                    Type: List PositiveInteger

for i in 1..#a repeat output(a.i)
 1
 2
 3
                    Type: Void

Iterate across this list using ”.” to access the elements of a list and the # operation to count its elements.

This type of iteration is applicable to anything that uses ”.”. You can also use it with functions that use indices to extract elements.

m := matrix [[1,2],[4,3],[9,0]]
 +-    -+
 | 1  2 |
 | 4  3 |
 | 9  0 |
 +-    -+
                   Type: Matrix Integer

Define m to be a matrix.

for i in 1..nrows(m) repeat output row(m.i)
 [1,2]
 [4,3]
 [9,0]
                   Type: Void

Display the rows of m.

You can iterate with for-loops.

for i in 1..5 repeat
  if odd?(i) then iterate
  output(i)
 2
 4
                   Type: Void

Display the even integers in a segment.

for i in n..m by s repeat

By default, the difference between values taken on by a variable in loops such as

for i in n..m repeat ...

is 1. It is possible to supply another, possibly negative, step value by using the by keyword along with for and in. Like the upper and lower bounds, the step value following the by keyword must be an integer. Note that the loop

for i in 1..2 by 0 repeat output(i)

will not terminate by itself, as the step value does not change the index from its initial value of 1.

for i in 1..5 by 2 repeat output(i)
 1
 3
 5
                    Type: Void

This expression displays the odd integers between two bounds.

for i in 5..1 by -2 repeat output(i)
 5
 3
 1
                    Type: Void

Use this to display the numbers in reverse order.

for i in n.. repeat

If the value after the ”..” is omitted, the loop has no end test. A potentially infinite loop is thus created. The variable is given the successive values n, n+1, n+2, ... and the loop is terminated only if a leave or return expression is evaluated in the loop body. However, you may also add some other modifying clause on the repeat, for example, a while clause, to stop the loop.

for i in 15.. while not prime?(i) repeat output(i)
 15
 16
                    Type: Void

This loop displays the integers greater than or equal to 15 and less than the first prime number greater than 15.

for x in l repeat

Another variant of the for loop has the form:

for x in list repeat loopbody

This form is used when you want to iterate directly over the elements of a list. In this form of the for loop, the variable x takes on the value of each successive element in l. The end test is most simply stated in English: “are there no more x in l?”

l := [0, -5, 3]
 [0, -5, 3]
                    Type: List Integer

for x in l repeat output(x)
 0
 -5
 3
                    Type: Void

This displays all of the elements of the list l, one per line.

Since the list constructing expression

expand [n..m]

creates the list

[n, n+1, ..., m]

you might be tempted to think that the loops

for i in n..m repeat output(i)

and

for x in expand [n..m] repeat output(x)

are equivalent. The second form first creates the expanded list (no matter how large it might be) and then does the iteration. The first form potentially runs in much less space, as the index variable i is simply incremented once per loop and the list is not actually created. Using the first form is much more efficient.

Of course, sometimes you really want to iterate across a specific list. This displays each of the factors of 2400000:

for f in factors(factor(2400000)) repeat output(f)
 [factor= 2, exponent= 8]
 [factor= 3, exponent= 1]
 [factor= 5, exponent= 5]
                    Type: Void

Table Of Contents

This Page