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

REBOL 3 Concepts: Expressions: Words

Pending Revision

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

Expressions are built from values and words. Words are used to represent meaning. A word can represent an idea or it can represent a specific value.

In the previous examples in this chapter, a number of words were used within expressions without explanation. For instance, the do, reduce, and try words are used, but not explained.

Words are evaluated somewhat differently than directly expressed values. When a word is evaluated, its value is looked up, evaluated, and returned as a result. For example, if you type the following word:

zero
0

the value 0 is returned. The word zero is predefined to be the number zero. When the word is looked up, a zero is found and is returned.

When words like do and print are looked up, their values are found to be functions, rather than simple values. In such cases, the function is evaluated, and the result of the function is returned.

Contents

Word Names

Words are composed of alphabetic characters, numbers, and any of the following characters:

? ! . ' + - * & | = _ ~

A word cannot begin with a number, and there are also some restrictions on words that could be interpreted as numbers. For example, -1 and +1 are numbers, not words.

The end of a word is marked by a space, a new line, or one of the following characters:

[ ] ( ) { } " : ; /

Thus, the brackets of a block are not part of a word. For example, the following block contains the word test :

[test]

The following characters are not allowed in words as they cause words to be misinterpreted or to generate an error:

@ # $ % ^ ,

Words can be of any length, but words cannot extend past the end of a line:

this-is-a-very-long-word-used-as-an-example

The following lines provide examples of valid words:

Copy print test
number?  time?  date!
image-files  l'image
++ -- == +-
***** *new-line*
left&right left|right

REBOL is not case sensitive. The following words all refer to the same word:

blue
Blue
BLUE

The case of a word is preserved when it is printed.

Words can be reused. The meaning of a word is dependent on its context, so words can be reused in different contexts. There are no keywords in REBOL. You can reuse any word, even those that are predefined in REBOL. For instance, you can use the word if in your code differently than the REBOL interpreter uses this word.

Pick Good Words

Pick the words you use carefully. Words are used to associate meaning. If you pick your words well, it will be easier for you and others to understand your scripts.

Word Usage

Words are used in two ways: as symbols or as variables. In the following block, words are used as symbols for colors.

[red green blue]

In the following line:

print second [red green blue]
green

the words have no meaning other than their use as names for colors. All words used within blocks serve as symbols until they are evaluated.

When a word is evaluated, it is used as a variable. In the previous example, the words print and second are variables that hold native functions which perform the required processing.

A word can be written in four ways to indicate how it is to be treated, as shown in [bad-link:concepts/word.txt] Formats.

Notation Definition Notes
word Get the natural value of the word. If the value is a function, evaluate it, otherwise return it.
word: Set the word to a value. We do not use = for assignment!
:word Get the value of a word without evaluating it. Useful for getting the value of a function.
'word Use the word as a symbol. We treat it as is and do not evaluate it.
/word Use the word as a refinement symbol. For functions, objects, file-paths, special fields.

Setting Words

A word followed by a colon (:) is used to define or set its value:

age: 42
lunch-time: 12:32
birthday: 20-March-1990
town: "Dodge City"
test: %stuff.r

You can set a word to be any type of value. In the previous examples, words are defined to be integer, time, date, string, and file values. You can also set words to be more complex types of values. For example, the following words are set to block and function values:

towns: ["Ukiah" "Willits" "Mendocino"]
code: [if age > 32 [print town]]
say: func [item] [print item]
Why Words Are Set This Way

In many langages words are set with an equal sign, such as:

age = 42

In REBOL words are set with a colon. The reason for this is important. It makes the set operation on words into a single lexical value. The representation for the set operation is atomic.

The difference between the two approaches can be seen in this example.

print length? [age: 42]
2
print length? [age = 42]
3

REBOL is a reflective language, it is able to manipulate its own code. This method of setting values allows you to write code that easily manipulates set-word! operations as a single unit.

Of couse, the other reason is that the equal sign (=) is used as a comparision operator.

Multiple words can be set at one time by cascading the word definitions. For example, each of the following words are set to 42:

age: number: size: 42

Words can also be set with the set function:

set 'time 10:30

In this example, the line sets the word time! to 10:30. The word time! is written as a literal (using a single quote) so that it will not be evaluated.

The set function can also set multiple words:

set [number num ten] 10

print [number num ten]
10 10 10

In the above example, notice that the words do not need to be quoted because they are within a block, which is not evaluated. The print function shows that each word is set to the integer 10.

If set is provided a block of values, each of the individual values are set to the words. In this example, one, two, and three are set to 1, 2, and 3:

set [one two three] [1 2 3]

print three
3
print [one two three]
1 2 3

See the [bad-link:concepts/words.txt] Section in the [bad-link:concepts/.txt] Values Appendix for more about setting words.

Getting Words

To get the value of a word that was previously defined, place a colon (:) at the front of the word. A word prefixed with a colon obtains the value of the word, but does not evaluate it further if it is a function. For example, the following line:

drucken: :print

defines a new word, drucken (which is German for print), to refer to the same function print does. This is possible because the get-word (:) returns the function for print, but does not evaluate it.

Now, drucken performs the same function as print :

drucken "test"
test

Both print and drucken are set to the same value, which is the function that does printing.

This can also be accomplished with the get function. When given a literal word, get returns its value, but does not evaluate it:

stampa: get 'print

stampa "test"
test

The ability to get the value of a word is also important if you want to determine what the value is without evaluating it. For example, you can determine if a word is a native function using the following line:

print native? :if
true

Here the get returns the function for if. The if function is not evaluated, but rather it is passed to the native? function which checks if it is a native datatype. Without the colon, the if function would be evaluated, and, because it has no arguments, an error would occur.

Literal Words

The ability to deal with a word as a literal is useful. Both set and get, as well as other functions like value?, unset!, protect, and unprotect, expect a literal value.

Literal words can be written in one of two ways: by prefixing the word with a single quotation mark, also known as a tick, (`) or by placing the word in a block.

You can use a tick in front of a word that is evaluated:

word: 'this

In the above example, the word! variable is set to the literal word this, not to the value of this. The word! variable just uses the name symbolically. The example below shows that if you print the value of the word, you will see the this word:

print word
this

You can also obtain literal words from an unevaluated block. In the following example, the first function fetches the first word from the block. This word is then set to the word variable.

word: first [this and that]

Any word can be used as a literal. It may or may not refer to a value. For example, in the example below the word here has no value. The word print does have a value, but it can still be used as a literal because literal words are not evaluated.

word: 'here
print word
here
word: 'print
print word
print

The next example illustrates the importance of literal values:

video: [
    title "Independence Day"
    length 2:25:24
    date   4/july/1996
]
print select video 'title
Independence Day

In this example, the word title is searched for in a block. If the tick was missing from title, then its natural value would be used. If title has no natural value, an error is displayed.

See the [bad-link:concepts/words.txt] Section in the [bad-link:concepts/values.txt] Appendix for more information about word literals.

Unset Words

A word that has no value is unset!. If an unset word is evaluated, an error will occur:

>> outlook
** Script Error: outlook has no value.
** Where: outlook

The error message in the previous example indicates that the word has not been set to a value. The word is unset. Do not confuse this with a word that has been set to none!, which is a valid value.

A previously defined word can be unset at any time using unset! :

unset 'word

When a word is unset, its value is lost.

To determine if a word has been set, use the value? function, which takes a literal word as its argument:

if not value? 'word [print "word is not set"]
word is not set

Determining whether a word is set can be useful in scripts that call other scripts. For instance, a script may set a default parameter that was not previously set:

if not value? 'test-mode [test-mode: on]

Protecting Words

You can prevent a word from being set with the protect function:

protect 'word

An attempt to redefine a protected word causes an error:

word: "here"
** Script Error: Word word is protected, cannot modify.
** Where: word: "here"

A word can be unprotected as well using unprotect :

unprotect 'word
word: "here"

The protect and unprotect functions also accept a block of words:

protect [this that other]

Important function and system words can be protected using the [bad-link:functions/protect-system.txt] function. Protecting function and system words is especially useful for beginners who might accidentally set important words. If [bad-link:functions/protect-system.txt] is placed in your user.r file, then all predefined words are protected.


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