Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

2009-05-24

JavaScript & REBOL

After working with both languages a great deal, I’ve come to the realization that JavaScript is the language in common use that’s most akin to REBOL. There’s still a very wide gulf, but there are enough similarities to make it worth a mention. (Not much more than a mention, though.)

At first glance, JavaScript and REBOL don’t look much alike, even when the code is doing the same thing.

// JavaScript
function foo(s) {
 return s + 'foo';
}
; REBOL
foo: func [s [string!]] [
 rejoin [s "foo"]
]

We can start to make them look a little more similar if we put the JavaScript inside an object literal and the REBOL inside a block. We’ll also omit the type specifier from the REBOL function, since JavaScript has no equivalent.

{
 foo: function(s) {
  return s + 'foo';
 }
}
[
 foo: func [s] [
  rejoin [s "foo"]
 ]
]

(I should point out that a block and an object literal are not equivalent, but their capabilities overlap a little bit. REBOL’s blocks are much more powerful.)

And that’s about as far as we can go with that. Anyway, it’s not lexical similarity that concerns me here, but functional similarity. For instance, both languages are scripting languages in the sense that they are not (usually) compiled. No big deal there. That’s true of a long list of languages.

However, both languages are prototype languages, and that’s certainly not true of a lot of languages.

function Foo() {
 this.watusi = 3;
}

function Bar() {
 this.watusi = 4;
}

Bar.prototype = Foo;

In REBOL, it’s similar, although in my opinion slightly more elegant, even if its syntax looks a bit strange to the curly bracers.

foo: make object! [watusi: 3]
bar: make foo [watusi: 4]

The serialized form of both languages is the language itself. In JavaScript, the JSON format is often used as a way to communicate between client and server. A very similar thing can be done with REBOL, although it has no specific name. (There really isn’t any need to have a special name or notation in REBOL. It’s just REBOL. In fact, being used for messaging is one of the fundamental things REBOL was designed to do.)

{ // JavaScript object literal
 orderno: 37,
 items: [22, 873, 14] // A list of order item numbers
}

What you see above is exactly what the server would transmit. We’d use it in JavaScript by assigning it to a variable.

var order = getOrder(); // getOrder() returns the object literal specified above
alert(order.orderno);

Here’s one REBOL equivalent (of a great many). Here’s what we’d transmit:

orderno: 37
items: [22 873 14]

And here’s how we might use it:

order: get-order
print order/orderno

The reason I didn’t place the REBOL “object literal” inside a block is because it isn’t necessary. When the string is read from the server, the LOAD function will automatically place it inside a block. GET-ORDER would be implemented something like this:

get-order: does [
 make object! load http://localhost:999/foo
]

In this particular case I tried to make the REBOL look as close to the JavaScript as I could to emphasize their similarities. I would probably implement the above very differently in REBOL under ordinary circumstances, although there’s nothing wrong with how it was done here. Because REBOL has DSLs and the evaluation of blocks is deferred (unlike JavaScript’s object literals), we have quite a few more options.

Another similarity is that both languages allow functions to be passed as arguments.

function callF(f) {
 f();
}

callF(function(){
 alert('called!');
});
call-f: func [f [any-function!]] [
 f
]

call-f does [print "called!"]

Both languages are amazingly nimble, although in a flexibility contest REBOL would win easily. It can do everything JavaScript can do and then some. Everything except manipulate the DOM, that is.