Rebol is an odd language with an odd history. It was originally put together in 1997 as an answer to the many things that plague modern programmers. The goal was to create a
language construction set using what we've learned from all the crazy trial-and-error in other languages. For instance, have you ever wondered
why we use curly braces? In Rebol, square brackets are used (saving your shift key a lot of work [0]).
Alright, enough semantics, let's get into the real part of coding.
Download the Rebol binary. While you're waiting, notice that you're not waiting, because the binaries are only half a megabyte. This gets really impressive when you realize just how much is in Rebol. Anyway, don't forget to chmod +x if you're on a good operating system.
So let's run through a basic "Hello World." Step one:
>> print "Hello World!"
Well, that was boring. How's about instead of going through the same boring syntactical tutorials, we check out the constructing power of Rebol and write helloworld in
our own language? Alright, now we're cooking.
To do this, I'll need to get a bit academic for a second (sorry, it'll be quick). Everything you punch into the interactive shell (also known as
REPL) is evaluated in Rebol's DO dialect. In Rebol, a dialect consists of a set of instructions to work with a given input [1]. Let's take a look at the
PARSE dialect, which takes the following format:
parse input rules /all /case
Let's ignore /all and /case for now and focus on the cool part. Let's make an incredibly basic language where "a" is syntax for sending the string "Hello " to system.out and "b" does the same, but with the string "World!\n". We could implement something like this in JavaScript like so:
While it's only a couple lines, it's still very difficult to extend. In Rebol, it looks something like this:
parse "abc" [any ["b" (print "world!") | "a" (prin "Hello ")]]
The first two bits are simple: parse enters the PARSE dialect and "abc" is the input we're passing in. The rules section is what we're really after.. Let's break it down:
[any ;If the parser finds any of the following
["b" ;an instance of "b"
(print "world!") ;Output "world!" with a newline
;parens mean that this code block will be executed in the DO dialect
| "a" (prin "Hello ")] ;Same as above, but using prin, which doesn't output a newline
]
There you have it, your own special language (an incredibly contrived one, to be sure, but one nonetheless). However, that's nowhere near as powerful as PARSE gets. Let's taken on an interesting problem: determining if a mathematical equation is valid. Benjamin Gruenbaum provides the following example in JS:
As you can see, this task is
much more difficult for JS to express. It's a tad harder in Rebol, but not nearly as much. To simplify things, we're going to do some assignment (using a colon instead of the equals sign, example taken from the
Rebol docs slightly modified to reflect the latest version of Rebol):
expr: [term ["+" | "-"] expr | term]
term: [factor ["*" | "/"] term | factor]
factor: [primary "**" factor | primary]
primary: [some digit | "(" expr ")"]
digit: charset "0123456789"
The important thing to notice here is the recursive nature of the instructions. "expr" is the top-level one you'll pass to the parse command:
parse "1+2*(3-2)/4" expr
== true
parse trim/all "1 + 2 * ( 3 - 2 ) / 4" expr ;use "trim/all" to remove whitespace
== true
There's much more in Rebol, so come to our
our chat room and find out! (This is a StackExchange chat, so you'll need 20 reputation on
StackOverflow to talk).
[0] US keyboard only (sorry!)
[1] It's
like a function, only more powerful. Every expression runs in a dialect. You can read about dialects
in the docs or
Wikipedia.