REBOL 3 Docs Guide Concepts Functions Datatypes Errors
  TOC < Back Next >   Updated: 18-Feb-2009 Edit History  

REBOL 3 Concepts: Expressions: Loops

Pending Revision

This document was written for R2 and has yet to be revised for R3.

The while and until functions above where used to loop until a condition was met. There are also several functions that let you loop for a specified a number of times.

Contents

Loop

The loop function evaluates a block a specified number of times. The following example prints a line of 40 dashes:

loop 40 [prin "-"]
==========================-

Note that the prin function is similar to the print function, but prints its argument without a line termination.

The loop function returns the value of the final evaluation of the block:

i: 0
print loop 40 [i: i + 10]
400

Repeat

The repeat function extends loop by allowing you to monitor the loop counter. The repeat function's first argument is a word that will be used to hold the count value:

repeat count 3 [print ["count:" count]]
count: 1
count: 2
count: 3

The final block value is also returned:

i: 0
print repeat count 10 [i: i + count]
55

In the previous examples, the count word only has its value within the repeat block. In other words, the value of count is local to the block. After repeat finishes, count returns to any previous set value.

For

The for function extends repeat by allowing the starting value, the ending value, and the increment to the value to be specified. Any of the values can be positive or negative.

The example below begins at zero and counts to 50 by incrementing 10 each time through the loop.

for count 0 50 10 [print count]
0
10
20
30
40
50

The for function cycles through the loop up to and including the ending value. However, if the count exceeds the ending value, the loop is still terminated. The example below specifies an ending value of 55. That value will never be hit because the loop increments by 10 each time. The loop stops at 50.

for count 0 55 10 [prin [count " "]]
0 10 20 30 40 50

The next example shows how to count down. It begins at four and counts down to zero one at a time.

for count 4 0 -1 [print count]
4
3
2
1
0

The for function also works for decimal numbers, money, times, dates, series, and characters. Be sure that both the starting and ending values are of the same datatype. Here are several examples of using the for loop with other datatypes.

for count 10.5 0.0 -1 [prin [count " "]]
10.5 9.5 8.5 7.5 6.5 5.5 4.5 3.5 2.5 1.5 0.5
for money $0.00 $1.00 $0.25 [prin [money " "]]
$0.00 $0.25 $0.50 $0.75 $1.00
for time 10:00 12:00 0:20 [prin [time " "]]
10:00 10:20 10:40 11:00 11:20 11:40 12:00
for date 1-jan-2000 4-jan-2000 1 [prin [date " "]]
1-Jan-2000 2-Jan-2000 3-Jan-2000 4-Jan-2000
for char #"a" #"z" 1 [prin char]
abcdefghijklmnopqrstuvwxyz

The for function also works on series. The following example uses for on a string value. The word end is defined as the string with its current index at the d character. The for function moves through the string series one character at a time and stops when it reaches the character position defined to end:

str: "abcdef"
end: find str "d"
for s str end 1 [print s]
abcdef
bcdef
cdef
def

Foreach

The foreach function provides a convenient way to repeat the evaluation of a block for each element of a series. It works for all types of block and string series.

In the example below, each word in the block will be printed:

colors: [red green blue]
foreach color colors [print color]
red
green
blue

In the next example, each character in a string will be printed:

string: "REBOL"
foreach char string [print char]
R
E
B
O
L

In the example below, each filename in a directory block will be printed:

files: read %.
foreach file files [
    if find file ".t" [print file]
]
file.txt
file2.txt
newfile.txt
output.txt

When a block contains groups of values that are related, the foreach function can fetch all the values of the group at the same time. For example, here is a block that contains a time, string, and price. By providing the foreach function with a block of words for the group, each of their values can be fetched and printed.

movies: [
     8:30 "Contact"      $4.95
    10:15 "Ghostbusters" $3.25
    12:45 "Matrix"       $4.25
]

foreach [time title price] movies [
    print ["watch" title "at" time "for" price]
]
watch Contact at 8:30 for $4.95
watch Ghostbusters at 10:15 for $3.25
watch Matrix at 12:45 for $4.25

In the above example, the foreach value block, [''time title price], specifies that three values are to be fetched from movies for each evaluation of the block.

The variables used to hold the foreach values are local to the block. Their value are only set within the block that is being repeated. Once the loop has exited, the variables return to their previously set values.

Forall and Forskip

Similar to foreach, the forall function evaluates a block for every value in a series. However, there are some important differences. The forall function is handed the series that is set to the beginning of the loop. As it proceeds through the loop, forall modifies the position within the series.

colors: [red green blue]
forall colors [print first colors]
red
green
blue

In the above example, after each evaluation of the block, the series is advanced to its next position. When forall returns, the color index is at the tail of the series.

To continue to use the series you will need to return it to its head position with the following line:

colors: head colors

The forskip function evaluates a block for groups of values in a series. The second argument to forskip is the count of how many elements to move forward after each cycle of the loop.

Like forall, forskip is handed the series with the series index set to where it is to begin. Then, forskip modifies the index position as it continues the loop. After each evaluation of the body block, the series index is advanced by the skip amount to its next index position. The following example demonstrates forskip :

movies: [
     8:30 "Contact"      $4.95
    10:15 "Ghostbusters" $3.25
    12:45 "Matrix"       $4.25
]

forskip movies 3 [print second movies]
Contact
Ghostbusters
Matrix

In the above example, forskip returns with the movies series at its tail position. You will need to use the head function to return the series back to its head position.

Forever

The forever function evaluates a block endlessly or until a it encounters the break function.

The following example uses forever to check for the existence of a file every ten minutes:

forever [
    if exists? %datafile [break]
    wait 0:10
]

Break

You can stop the repeated evaluation of a block with the break function. The break function is useful when a special condition is encountered and the loop must be stopped. The break function works with all types of loops.

In the following example, the loop will break if a number is greater than 5.

repeat count 10 [
    if (random count) > 5 [break]
    print "testing"
]
testing
testing
testing

The break function does not return a value from the loop unless a /return refinement is used:

print repeat count 10 [
    if (random count) > 5 [break/return "stop here"]
    print "testing"
    "normal exit"
]
testing
testing
testing
stop here

In the above example, if the repeat terminates without the condition occurring, the block returns the string normal exit. Otherwise, break/return will return the string stop here.


  TOC < Back Next > REBOL.com - WIP Wiki Feedback Admin