The extra line that sets all the variables to none is done to allow code to determine if the variable was actually set in the block. Not all variables may be present in each block. (The scope of these variables can be global or local to a function or object.)
Dialects
A REBOL dialect is a set of data structuring rules that lets you define specific meaningful sequences of REBOL words or data. Dialects are created in REBOL using the language's data structures, symbols, and native functions. Any sequence of values that must be interpreted through special code is considered a dialect. Listings One through Three are dialects because they require user code to interpret their structure. Listing Four is not a dialect, because it is actual code.
A dialect is defined as a specialized grammar that shares REBOL's common set of datatypes. A dialect is not specified as character patterns, but rather as datatype patterns within REBOL. Dialects are normally created by a programmer who understands the details of a specific domain. For instance, you can create a home control dialect that lets you send this message to your home:
Turn on porch light at 7:30 pm
Your home computer would interpret the message by running a REBOL dialect that understands actions like "turn on," objects like "porch light," and times like "7:30 pm."
There is no limit to the number or sophistication of the dialects that can be created. It is common practice for programmers to create sublanguages to better express and describe solutions. Chip designers, civil engineers, stock brokers, statisticians, financiers, travel agents, and other professionals have created their own specialized languages to become more productive within their specific domains. Other dialect examples are in Example 3. These dialects can become more involved and sophisticated depending on the requirements of the domain, as in Example 4.
Buy 10.5 gallons of gas at $1.42 each Sell 100 shares of "Acme" at $4.55 per share Display "river" image in center of screen Turn right 2 miles after "Perkins Road" exit
Example 3: Dialect examples.
Search for flight from SFO to JFK prefer "American" or "United" departs 1-June-2000 arrives before 10:30PM priced less than $450 or: Buy 1000 shares of "Acme" symbol ACME at or below $4.60 expires on 6-June-2000 account #ACN-456-987 confirm with [email protected]
Example 4: More complex examples.
These examples are wordy in order to make them look more like English; however, REBOL should not be mistaken for English. It is not. The similarity to English is done to make dialects easier for users. Messages can be written in a more concise format if necessary. For instance, Listing Five shows dialect lines that are used to describe a graphical user interface in REBOL/View with its consumer interface dialect (CID is one of several user-interface dialects). Rather than use extra words, the meaning of each line is known from the words and datatypes that are used, such as text strings, numbers, image files, colors, blocks, and so on.
Listing Five
view layout 640x480 [ backdrop %trees.jpg title "Network Tester" text {Test that your network configuration is working by clicking on relevant buttons below.} pad 20 text "Network Tests:" yellow button "DNS" [read dns://www.rebol.com] button "Whois" [read whois://[email protected]] button "Finger" [read finger://[email protected]] button "Time" [read daytime://10.5.5.2] button "SMTP" [send [email protected] "Test"] button "POP" [read pop://user:[email protected]] button "HTTP" [read http://www.rebol.com] ]
In addition to user-defined dialects, REBOL has several built-in dialects. The specification of a function and its arguments is done in a dialect of REBOL that accepts argument names, their acceptable datatypes, description strings, functional refinements, and more. Listing Six shows the append
function specification. Other dialects are used in REBOL for the secure
and parse
functions.
Listing Six
append: func [ {Appends a value to the tail of a series.} series [series! port!] {Series to append to} value {Value to append} /only {Appends a block value as a block} ]
Defining Dialects
A dialect can be formal or informal. A formal dialect requires a grammar be provided to the parse
function. An informal dialect requires no such specification. Listings One through Three are informal dialects. To specify a formal dialect, grammar rules are provided to the parse
function. Listing Seven is a stock trade and its dialect.
Listing Seven
trade: [ Sell 100 shares of "Acme" at $4.55 per share ] stock-dialect: [ set action ['sell | 'buy] set shares integer! 'shares 'of set company string! 'at set price money! 'per 'share ] parse trade stock-dialect
The stock dialect is a block that defines the rules of the grammar for the stock dialect. These rules are actually a dialect of REBOL, so the values within it have a different meaning than they would in normal REBOL code.
The first line indicates that a variable should be set to hold either the word "sell" or "buy." The vertical bar separates the alternates. Whichever is found will be set to the action variable. If neither is found, then the parse
function will return immediately with a false value. This is similar to the standard Backus Naur Form (BNF) grammar specifications used to specify most languages and protocols. The remaining lines set other values for the number of shares, company name, and price per share. The words that begin with a tick (single quote) are literal words and must appear as specified within the grammar. Many of these words can be made optional by using the opt keyword, as in Listing Eight. This new grammar allows all of the stock trades in Listing Nine. Listing Ten is the code that calls the parse
function with the grammar rules and prints the result.
Listing Eight
set action ['sell | 'buy] set shares integer! opt 'shares opt 'of set company string! 'at ['below | 'above | none] set price money! opt ['per 'share]
Listing Nine
Sell 100 shares of "Acme" at $4.55 per share Sell 100 shares "Acme" at $4.55 per share Sell 100 shares "Acme" at above $4.55 per share Sell 100 of "Acme" at $4.55 per share Sell 100 of "Acme" at below $4.55 Sell 100 "Acme" at $4.55
Listing Ten
either parse trade stock-dialect [ print [action shares company price] ][ print "stock trade error" ]
Simple Network Dialect
The stock dialect parses the trade, but does nothing other than print the result. Most of the time, you'll want to associate specific actions to parts of a dialect. The dialect in Listing Eleven defines a simple network command language that can move web pages between systems and send a progress report to a network manager. This is a complete script example that includes a REBOL header.
Listing Eleven
REBOL [ Title: "Dr. Dobb's Example" Date: 28-Mar-2000 Version: 1.0.2 Needs: [core 2.3.0] ] commands: [ manager is [email protected] access with ftp://user:[email protected]/pages inform "beginning update..." download %index.html download %sitemap.html to %oldsitemap.html upload %new-index.html to %index.html upload %logo.jpg notify "home page has been updated" quit ] net-dialect: [ 'manager opt 'is set who email! 'access opt 'with set site url! some [ 'download file-rule (print ["Downloading:" src] write/binary dest read/binary site/:src) | 'upload file-rule (print ["Uploading:" src] write/binary site/:dest read/binary src) | 'notify set message string! (send who message) | 'inform set message string! (print message) | 'quit (quit) | here: (print ["Unknown:" mold here] halt) ] ] file-rule: [set src file! ['to set dest file! | none (dest: src)]] if error? try [parse commands net-dialect][ send who "Script failed" ]
The block of commands holds actions that the net dialect block parses with specified grammar rules. In addition, there is a file rule that is used within the net dialect block. The parse
function is called with error handling (the try
function) just in case a mistake is not caught by the dialect grammar. This script can easily be modified to load the command block from other files.
Conclusion
Communication is the exchange and interpretation of information. To communicate, we need to share a common language. However, in many cases we are dealing with a specific domain, where a dialect can provide greater productivity, easier maintenance, and quicker time-to- market. There are examples in the world around us from VCRs to toasters and from home control to automobile engines that can benefit from this approach. This becomes even more essential in today's distributed computing environment, where complexity and size of software solutions have created serious development barriers. Within these specific domains, REBOL provides a powerful tool for breaking through that code barrier.
Carl is the founder of REBOL Technologies and one of the designers of the Amiga operating system. He can be contacted at [email protected].