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

REBOL 3 Concepts: Expressions: Evaluation

Pending Revision

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

To evaluate an expression is to compute its value. REBOL operates by evaluating the series of expressions constituting a script and then returning the result. Evaluating is also called running, processing, or executing a script.

Evaluation is performed on blocks. Blocks can be typed at the console or loaded from a script file. Either way, the process of evaluation is the same.


Evaluating Console Input

Any expression that can be evaluated in a script, can also be evaluated from the REBOL prompt, providing a simple means of testing individual expressions in a script.

For example, if you type the following expression at the console prompt:

>> 1 + 2
== 3
About The Code Examples...

In the example above, the console prompt (>>) and result indicator (==) are shown to give you an idea of how they appear in the console. For the examples that follow, the prompt and result strings are not shown. However, you can assume that these examples can be typed into the console to verify their results.

Evaluating Simple Values

Since the value of directly expressed values is known, they simply return their values. For example, if you type the following line:


the value 10:30 is returned. This is the behavior of all directly expressed values. It includes:

integer    1234
decimal    12.34
string     "REBOL world!"
time       13:47:02
date       30-June-1957
money      $12.49
pair       100x200
char       #"A"
binary     #{ab82408b}
issue      #707-467-8000
tag        <IMG SRC="xray.jpg">
file       %xray.jpg
block      [milk bread butter]

Evaluating Blocks

Normally, blocks are not evaluated. For example, typing the following block:

[1 + 2]
[1 + 2]

The block is not evaluated; it is simply treated as data.

To evaluate a block, use the do function, as shown in the following example:

do [1 + 2]

The do function returns the result of the evaluation. In the previous example, the number 3 is returned.

If a block contains multiple expressions, only the result of the last expression is returned:

do [
    1 + 2
    3 + 4

In this example, both expressions are evaluated, but only the result of the 3 + 4 expression is returned.

There are a number of functions such as if, loop, while, and foreach that evaluate a block as part of their function. These functions are discussed in detail later in this chapter, but here are a few examples:

if time > 12:30 [print "past noon"]
past noon
loop 4 [print "looping"]

This is important to remember: blocks are treated as data until they are explicitly evaluated by a function. Only a function can cause them to be evaluated.

Reducing Blocks

When you evaluate a block with do, only the value of its last expression is returned as a result. However, there are times when you want the values of all the expressions in a block to be returned. To return the results of all of the expressions in a block, use the reduce function. In the following example, reduce is used to return the results of both expressions in the block:

reduce [
    1 + 2
    3 + 4
[3 7]

In the above example, the block was reduced to its evaluation results. The reduce function returns results in a block.

The reduce function is important because it enables you to create blocks of expressions that are evaluated and passed to other functions. reduce evaluates each expression in a block and puts the result of that expression into a new block. That new block is returned as the result of reduce.

Some functions, like print, use reduce as part of their operation, as shown in the following example:

print [1 + 2  3 + 4]
3 7

The rejoin, reform, and remold functions also use reduce as part of their operation, as shown in the following examples:

print rejoin [1 + 2  3 + 4]
print reform [1 + 2  3 + 4]
3 7
print remold [1 + 2  3 + 4]
[3 7]

The rejoin, reform, and remold functions are based on the join, form, and mold functions, but reduce their blocks first.

Evaluating Scripts

The do function can be used to evaluate entire scripts. Normally, do evaluates a block, as shown in the following example:

do [print "Hello!"]

But, when do evaluates a file name instead of a block, the file will be loaded into the interpreter as a block, then evaluated as shown in the following example:

do %script.r
A REBOL Header is Required

For a script file to be evaluated, it must include a valid REBOL header, which is described in the scripts Chapter. The header identifies that the file contains a script and not just random text.

Evaluating Strings

The do function can be used to evaluate expressions that are found within text strings. For example, the following expression:

do "1 + 2"

returns the result 3. First the string is converted to a block, then the block is evaluated.

Evaluating strings can be handy at times, but it should be done only when necessary. For example, to create a REBOL console line processor, type the following expression:

forever [probe do ask "=> "]

The above expression would prompt you with => and wait for you to type a line of text. The text would then be evaluated, and its result would be printed. (Of course, it's not really quite this simple, because the script could have produced an error.)

Unless it is necessary, evaluating strings is not generally a good practice. Evaluating strings is less efficient than evaluating blocks, and the context of words in a string is not known. For example, the following expression:

do form ["1" "+" "2"]

is much less efficient than typing:

do [1 + 2]

REBOL blocks can be constructed just as easily as strings, and blocks are better for expressions that need to be evaluated.

Evaluation Errors

Errors may occur for many different reasons during evaluation. For example, if you divide a number by zero, evaluation is stopped and an error is displayed

100 / 0
** Math Error: Attempt to divide by zero.
** Where: 100 / 0

A common error is using a word before it has been defined:

size + 10
** Script Error: size has no value.
** Where: size + 10

Another common error is not providing the proper values to a function in an expression:

10 + [size]
** Script Error: Cannot use add on block! value.
** Where: 10 + [size]

Sometimes errors are not so obvious, and you will need to experiment to determine what is causing the error.

  TOC < Back Next > - WIP Wiki Feedback Admin