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.
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.
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.
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.
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