Channels ▼
RSS

Embedded Systems

The REBOL Scripting Language

Source Code Accompanies This Article. Download It Now.


People who speak English understand messages such as "turn on the light" or "record TV channel 7 at 8 pm." But can your computer understand the same messages? The question is not whether your computer can understand English, but rather, can it understand these specific messages? In other words, is it possible to share a common language with your computer, even if it's not exactly English?

This is the goal of REBOL, short for "Relative Expression-Based Object Language." REBOL was designed to make it easier to communicate between computers, or between people and computers, using context-dependent sublanguages. REBOL is unlike traditional programming languages such as C, Basic, or Java. The language has no keywords and little syntax. Although it can be used for programming, writing functions, and performing processes, its greatest strength is the ability to easily create domain-specific languages or dialects.

In addition, REBOL is a highly polymorphic and reflective language. The former means that the language applies its functions to a wide variety of datatypes in a consistent manner. The latter indicates that the language can be dynamically introspective about itself. This property is quite difficult to obtain in language design, but allows REBOL to be descriptive and self referential. In fact, REBOL is metacircular: It is able to serve as its own metalanguage, eliminating the need for preprocessing and macros. The result is a language with a powerful and dynamic means of expression.

REBOL scripts are machine independent and run on 37 different CPU/OS platforms. The language has several networking protocols built in, including HTTP, FTP, NNTP, SMTP, POP, Finger, Whois, Daytime, and DNS. In addition, it handles multiple proxy servers and can communicate directly at the TCP/IP level. Finally, REBOL is compact, requiring only a 200 KB download; it can be downloaded free of charge from http://www.rebol.com/.

REBOL Programming

REBOL is not a conventional language. It breaks a number of rules. For instance, REBOL has more than 40 datatypes built in (contrasted to languages such as C that have five or six datatypes). This lets you write values such as dates, times, money, e-mail, HTML/XML tags, and URLs directly in a script using a format that is already familiar to you. In addition, the datatypes are always part of the system. You don't need to hunt around for libraries or include files.

This simple script creates a network agent to check a web site every 10 minutes. If the web page fails to download, an e-mail is sent to the webmaster:

forever [

   if error? try [ 

      read http://www.site.dom

   ] [

   send webmaster@site.dom 

      "Site is down."

   ]

   wait 0:10


]

This example checks every hour to determine if a web site has changed:

old-sum: checksum read http://www.site.dom

until [

    wait 1:00

    old-sum <> checksum read http://www.site.dom

]

send me@site.dom "Web site changed!"

The brackets [] indicate blocks, which can hold both code and data values. They can be of any length and may contain other blocks. The values within a block can be of various datatypes. These values are written in free format, with no significance to spacing or lines. Table 1 shows the available datatypes.

Table 1: Primary REBOL datatypes. (a) Numerical datatypes; (b) character datatypes; (c) block datatypes; (d) word datatypes; (e) function datatypes; (f) object datatypes; (g) special datatypes.

REBOL is a symbolic language. Words are used as both symbols and as variables. When used as symbols, you're not interested in their value, only what they stand for.

A block can be evaluated. This operation looks up the values for words and performs functions. The values can be passed as arguments to functions, and values are returned as results. All operations in REBOL are functions. For instance, you can write:

if time > 11:30 [print "Lunch"]

But you can also write code such as:

condition: (time > 11:30)


action: [print "Lunch"]


if condition action

A variable definition is done with a colon, not an equal (which is used for equality). A variable can hold a function as well as any other type of value.

It is worth noting that REBOL has no keywords and little syntax. This may seem foreign if you know C, Java, or Basic, but these features are important for creating dialects.

As mentioned earlier, REBOL is a highly polymorphic and reflective language. The reflective property can be seen when using the REBOL internal help, which uses function argument specifications to generate help information. For instance, the help lines in Example 1 were generated from the definition of the switch function. This introspective database is also used when generating error messages, as in Example 2.


USAGE:
     SWITCH value cases /default case
DESCRIPTION:
     Selects a choice and evaluates what follows it.
     SWITCH is a function.
ARGUMENTS:
     value -- Value to search for. (Type: any)
     cases -- Block of cases to search. (Type: block)
REFINEMENTS:
     /default
         case -- Default case if no others are found. (Type: any)

Example 1: Help lines in REBOL.


switch 20
   ** Script Error: switch expected cases argument of type: block.
   ** Where: switch 20

Example 2: Generating error messages.

REBOL Data Structuring

REBOL data structures are also formed with blocks. They can contain values of any datatype, including words, and the values may appear in any order. The freedom of order establishes the basis for dialects and will be explained in the next section.

The data held within blocks can be referenced by its position, tag, type, evaluation, and dialect. Referencing by position is most common for groups of fixed-size structured data. For instance, Listing One defines a block of friends and related data. The position determines where information is held. Name is first, age is second, and e-mail is third.

Listing One
  friends: [
          "Bob"   24 bob@mob.dom
          "Sally" 28 sal@bol.dom
          "Julie" 30 jul@minespring.dom
  ]
  foreach [name age email] friends [
          send email reform ["Hi" name "How's it going?"]
  ]

Referencing data by tag is useful if the order of the data is irregular or contains entries of variable length, as in Listing Two. Words are used as tags to mark specific values. The words are not used as variables; they are just markers (similar to how XML tags its data). Similar to tags, datatypes can be used to reference specific items. Listing Three shows how you would find all e-mail addresses to send friends a quick hello.

Listing Two

friends: [
        name "Bob" "Marker" age 24
        name "Sally"
                age 28
                email sal@bol.dom
                phone #777-555-1111
        name "Julie" "Lober"
                email jul@minespring.dom
                site http://www.juliesite.dom
                city "New York"
]
while [friends: find friends 'name] [
        friends: next friends
        print first friends
]
friends: head friends

Listing Three
while [friends: find friends email!] [
        send first friends "Quick hello!"
        friends: next friends
]

Another method of referencing data requires evaluation of the data block in order to set variables to specific values. Here each value is assigned to a variable. This is done when the block is evaluated, as in Listing Four.

Listing Four

friends: [
        [name: "Bob Marker" age: 24]
        [name: "Sally"
                age: 28
                email: sal@bol.dom
                phone: #777-555-1111
        ]
        [name: "Julie Lober"
                email: jul@minespring.dom
                site: http://www.juliesite.dom
                city: "New York"
        ]
]
foreach person friends [
        set [name age email phone site city] none
        do person
        print name
]


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video