REBOL 3 Docs | Guide | Concepts | Functions | Datatypes | Errors |
TOC < Back Next > | Updated: 18-Apr-2009 Edit History |
Left to right and right to left.
In code: evaluating blocks you learned that code is held in data blocks that get directly evaluated.
In general, expressions are evaluated from left to right; however, within each expression evaluation occurs from right to left.
Take this example:
print length? join "exam" "ple"
The print and length? functions require one argument. The join function requires two arguments. You can divide the line into separate sections that are each evaluated.
We start with:
print length? join "exam" "ple
which evaluates to:
print length? "example"
and finally to:
print 7
This is called the substitution method of understanding evaluation. It is handy to remember.
Multiple expressions are written in the same way. You don't need separators, but we often will put new expressions on a separate line to make them more readable.
Here are three separate expressions:
print "reading web page..." data: read http://www.rebol.com print length? data
You could have written all these on one line, but the results would be the same.
How do you know where each expression begins and ends? It is determined by the arity (the number of arguments) required by each function. For example, print only takes one argument. Once it has that argument, evaluation advances to the next expression.
If you are not sure how many arguments a function requires, use help on it. However, for the most common functions, it won't take long for you to memorize them.
As mentioned in code: evaluating blocks a block returns a result. However, there are times when we want multiple results from a block.
Consider what happens when you write:
print ["results:" 1 + 2 3 * 4]
results: 3 12
Here the block passed to print is returning more than just one value.
As you can see below, the block result is no longer the same thing as:
do ["results:" 1 + 2 3 * 4]
12
When you need multiple results, rather than do, use reduce instead:
reduce ["results:" 1 + 2 3 * 4]
["results:" 3 12]
Notice that the substitution method of evaluating your results remains the same, but you keep all results in a block.
This is a very important concept in REBOL. It allows you to to pass, store, and return multiple values in a similar way to how you would handle a single value.
To make mathematical expressions easier to read, the language supports infix operators like plus, minus, multiply, divide, and a few others.
Operators are an exception to the above rule. Take the expression:
print 1 + 2
This is evaluated as:
print (1 + 2)
not as:
(print 1) + 2
Operators take precedence over normal functions. However, note that all operators have the same precedence. Operators are applied from left to right.
Take this example:
print 1 + 2 * 3 + 4 * 5
65
It evaluates left to right, using the substitution method:
print 3 * 3 + 4 * 5 print 9 + 4 * 5 print 13 * 5 print 65
Changing the order of the values changes the result:
print 2 * 3 + 1 + 4 * 5
55
So, it's just left-to-right, and operators take precedence over functions.
Looking at:
print 10 * sine 30 + 60
It evaluates to:
print 10 * sine 90 print 10 * 1.0 print 10.0
Parentheses can be used to control the order of evaluation:
(2 + 3) * (10 - 5)
25
That is the same as:
2 + 3 * (10 - 5)
When using length?, this is a common case:
if (length? "a string of chars") > 10 [print "ok"]
ok
Of course, you can reorder that line as:
if 10 <= length? "a string of chars" [print "ok"]
But, maybe that does not read as well, so another alternative is to use the greater? function instead of the operator:
if greater? length? "a string of chars" 10 [print "ok"]
TOC < Back Next > | REBOL.com - WIP Wiki | Feedback Admin |