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.
The `parse` function just looks like a single function you'd have to program once in JS to have the same behavior.
ReplyDeleteI don't think a single function is useful to show a programming language's strengths.
Hi Florian,
ReplyDeleteI think Rebol's parse is so comprehensive and performant that it's not very useful to just say it "looks like a single function you'd have to program once in JS". That's kind of like saying creating a JavaScript VM is no big deal - you can write one in JavaScript (see Continuum at http://benvie.github.com/continuum).
First, that doesn't say anything about how complex an endeavor that would be, but it's possible since, in the end, JS is a Turing-complete language.
Second, what performance (and memory consumption for a given task) would you get with this JS implementation? Rebol's parse uses highly-tuned C code to accomplish its neat 'tricks'. Sure, for a simple parser needed for a calculator, what's it matter? The reality is that parse is suitable for a very wide range of tasks.
A more interesting thing which could be said about parse is that it is actually the very thing to use when creating a language parser for a full-featured language like, hmmm, JavaScript.
Parse really is one of Rebol's 'killer features'. If all you see there is a quick function that you could hack up in JS, maybe you haven't looked closely enough.
Cheers,
Adrian
Loved how you wrote this post.
ReplyDeleteSo minimal, but so much. And you make me want to forget the little Rebol that I know, and then accident;y land on this page and then get to Rebol.
And I am too much of a newbie to say anything else, but being a newbie, the way you broke the single line example in the first case to multiple lines and with explaining comments was great from a newbie perspective.
-- KK. from the SO room.