REBOL in Ten Steps
Contents | ||
This is a brief overview of REBOL. It presents the basic ideas of REBOL in ten steps that should require only a few minutes to read.
Values
Values are the raw data of REBOL.
A wide variety of values can be written directly in REBOL. No special "constructor" is required. You simply write the values as is.
REBOL strives to use human-friendly forms for values. This makes scripts more readable. And, as you will see below, REBOL accepts more than one format for some values to allow for international variations.
Here are examples of a few of the different values (datatypes) of REBOL. Note below that in REBOL comments begin with a semicolon (;).
Numbers:
1234 -432 3.1415 1.23E12 0,01 1,2E12 ; non-British decimal format
Times:
12:34 20:05:32 0:25.34
Dates:
20-Apr-1998 20/Apr/1998 20-4-1998 1998-4-20 20-Apr-1998/12:32 ; date with time 20-Apr-1998/12:32-8:00 ; date with time and timezone
Money:
$12.34 USD$12.34 CAD$123.45 DEM$1234,56
Tuples:
3.1.5 ; version numbers 255.255.0 ; used for colors 199.4.80.7 ; Internet addresses
Coordinate Pairs:
5x10 100x100 -50x-25
Strings:
"Here is a string" {Here is another way to write a string that spans many lines and contains "quoted" strings.}
Tags:
<title> <h1> </h1> <a href="example.html">
Email:
info@rebol.com pres-bill@oval.whitehouse.gov
URLs:
http://data.rebol.com ; web site ftp://ftp.rebol.com/sendmail.r ; file transfer mailto:info@rebol.com ; another email format
Files:
%data.txt %images/photo.jpg %../scripts/*.r
Issues:
#707-467-8000 ; a phone number #0000-1234-5678-9999 ; a credit card number #MFG-932-741-A ; a model number
Binary:
#{0A6B14728C4DBEF5} ; hex encoded 64#{45kLKJOIU8439LKJklj} ; base-64 encoded
Where possible, REBOL allows the use of international formats for values such as decimal numbers, money, and dates.
Words
Words are the symbols of REBOL.
They are used to represent something directly as a word, or indirectly as a variable (more on this later).
You write words the same way as you do in most natural languages (such as English):
Show next picture Carl Cindy Brenda Joe Dan Install all files here country state city street zipcode on off true false one none
Hyphens and some other special characters can also be used. They are considered to be part of the word. These are all REBOL words:
number? time? date! image-files connection-times file-size ++ -- == +- ***** *new-line* left&right
The end of a word is marked by a space, a new line, or one of the characters:
[ ] ( ) { } " : ; /
Also, these characters can not appear within words:
/ @ # $ % ^ ,
Blocks
Values and words are grouped together in blocks. A block begins with a '[' and ends with a ']'. You can organize values and words in any order and over any number of lines. REBOL allows a free format within a block for creating databases, directories, tables, sets, sequences, code, functions, etc.
[white red green blue yellow orange black] ["Spielberg" "Back to the Future" 1:56:20 MCA] [ "Bill" billg@ms.com #315-555-1234 "Steve" jobs@apl.com #408-555-4321 "Ted" ted@gw2.com #213-555-1010 ] [ "John" 6894 0:55:68 "Dion" 68861 0:61:35 "Floyd" 46001 0:50:12 ]
Blocks are commonly used for code as well as for data:
if time > 10:30 [send jim news] loop 100 [print/only "*"] sites: [ http://data.rebol.com [save %reb.html data] http://www.cnn.com [print data] ftp://www.amiga.com [send cs@org.foo data] ] foreach [site action ] sites [ data: read site do action ]
Evaluation
Blocks can be evaluated to compute their results. The values and words of the block are computed from left to right. The examples below show how this works as if you typed into REBOL at the prompt. (Lines typed at the prompt create a block, even though the brackets [ ] are not shown):.
print "Hello REBOL" Hello REBOL send friend@rebol.com "Hello REBOL" color: [red green blue] pick color 3 blue loop 10 [prin "*"] ;(not a typo, see manual) ********** if today = 6-Jun-1999 [ send friend@rebol.com "Happy 40th birthday" ] loop 20 [ wait 8:00 send friend@rebol.com read http://www.cnn.com ] repeat count 3 [print ["count:" count]] count: 1 count: 2 count: 3
Parentheses can be used to group the order of evaluation:
(2 + 3) * (10 - 5) 25 (length? "boat") + 2 6
Variables
Words can be used as variables to hold values. A word followed by a colon sets its value:
age: 22 snack-time: 12:32 birthday: 20-Mar-1997 friends: ["John" "Paul" "George"]
A word used without a colon evaluates it:
print age 22 if current-time > snack-time [print snack-time] 12:32 print third friends George
A variable can be used to hold any type of value. In the examples above, the words print, if, > third are variables which hold functions. They happen to be predefined by REBOL, but they are otherwise no different from any other words.
Variables only have meaning within the context where they are defined. A context can span the entire program or be restricted to a particular block, object, or function. In the example below, the use function makes the word age local to the block that follows. Age is a local variable. Outside the block it may have other values, but that will not affect the value of age within the block.
use [age] [ age: "young" print age ]
Local variables are also created by functions, as will be described in the next section.
Functions
A function is a block which has local variables that are given new values each time the block is evaluated. The local variables are the arguments of the function. Functions can be created in several ways. Here is the most common:
sum: func [a b] [a + b]
This creates a new function which is set to the word sum. The first block describes the arguments of the functions and the second block is what is evaluated when the function is used (it adds two values and returns the result). To use the function:
print sum 2 3
5
When the sum function is applied, the value of a becomes 2 and the value of b becomes 3. They are added together and the result is returned, where it is then passed as an argument to the print function.
For some functions you may want local variables that are not arguments. Instead of using func in the case above, you can use function:
average: function [series] [total] [ total: 0 if zero? length? series [return 0] foreach value series [total: total + value] return total / (length? series) ]
The series is the argument and the total is a local variable used for calculation purposes. Notice that a return is used in two places to pass the result back as the result of the function. If no result was desired, an exit could have been used.
Paths
A path specifies a refinement. It provides a simple way to indicate that more information is needed. You are familiar with paths as they are used with files and URL's. The slash character (/) is used to separate the words within the path:
source/images/globe.jpg http://data.rebol.com/examples/simple.r
In REBOL, paths can also be used for blocks, functions, objects, and strings:
USA/CA/Ukiah/size ; block selection match/any ; function option account/balance ; object function names/12 ; string position
The example below shows the simplicity of using a block as a mini-database that is accessed with a path:
areas: [
Hopland [
phone #555-1234
site http://www.hopland.ca.gov
]
Ukiah [
phone #555-4321
site http://www.ukiah.com
email info@ukiah.com
]
]
print areas/ukiah/site
http://www.ukiah.com
Objects
An object is a group of variables which have values in a specific context. Objects are used for managing data structures which have more complex behavior. For instance, a bank account can benefit from using an object to specify its attributes and functions:
account: make object! [ name: "Flintstone" balance: $100 ss-number: #1234-XX-4321 deposit: func [amount] [balance: balance + amount] withdraw: func [amount] [balance: balance - amount] ]
The name, balance, and ss-number, deposit, and withdraw are local variables of the account object. The deposit and withdraw variables are functions which are defined locally within the object. The variables of the account can be accessed with a path:
print account/balance $100.00 account/deposit $300 print ["Balance for" account/name "is" account/balance] Balance for Flintstone is $400.00
To make another account with a new balance but with all the other values remaining the same:
checking-account: make account [ balance: $2000 ]
You can also create an account that extends the account object by adding the bank name and last activity date:
checking-account: make account [ bank: "Savings Bank" last-active: 20-Jun-1998 ] print checking-account/balance $2000.00 print checking-account/bank Savings Bank
Objects have a few other features, including hidden variables.
Messages
A REBOL message is simply a file of text that is sent from one place to another. It does not matter if the message is sent between computers, processes, or people -- the form of the message remains the same. They begin with a REBOL header which helps identify the content, age, and attributes:
REBOL [ Title: "Example Header" Date: 1-Sep-1998 Author: "Homer Simpson" Version: 1.0.0 Purpose: "Shows an example of a REBOL header" ]
The header may contain other information, depending on the purpose and importance of the message. The header is then followed by the content of the message itself. As shown in the sections above, it can contain data, code, or a mixture of both.
Messages can be sent over the existing Internet protocols such as the web, e-mail (SMTP & POP), news, and ftp. Messages can also be embedded in other forms of content, such as web pages or documentation files. In the example below, REBOL reads a message from a web site and evaluates it:
do http://data.rebol.com/test-msg.r
Rock'n and roll'n with REBOL
This example sends a short REBOL message via email:
send test@rebol.com read %short-msg.r
This example evaluates every message sent to your mailbox from other REBOLs:
foreach mail-msg email-port [ message: import email-template mail-msg if message/x-rebol [ remove mail-msg do message/content ] ]
The import function converts a text email message into a REBOL object for easy access. If the email contains an x-rebol line, then it was sent from REBOL.
Dialects
REBOL's greatest power comes from dialecting.
Dialects are blocks that carry condensed meaning through the use of a different grammar (ordering) of values and words. Dialects are usually unique and well-suited to the problems they are designed to solve.
You have already seen some simple dialects. For instance, the list of arguments to a function is a dialect that can contain many variations other than those which have been shown here. Other dialects also exist for parsing expressions and formatting output.
Here are a few examples of other dialects that might be written to solve particular problems. To be interpreted, each of every dialect requires parser written in REBOL. Parsers can be as small as a few lines of code, and do not normally require more than a page.
The first example is a video studio control script dialect:
[queue tape to 0:36:35] [roll tape] [wait until 0:37:07] [wipe tape to image with effect 3] [key title-text]
A graphical user interface dialect:
button [200 100] style-4 [play cruse-narration] button [* 120] style-4 [start scene 27] window [260 100] text-80 [select window area]
A soccer scheduler:
[team-12 plays team-32 on saturdays at 10:00] [team-12 must drive] [team-32 can play any day] [team-17 does not play on mondays]
An installer script:
Delete base-dir if earlier modification date Create base-dir if not existing Install %editor if newer Install %crash-protect if on Win32 and is newer Install %browser but never replacing existing Switch to %threads if pre-1.2-system
The possibilities are endless.