Here in 2024, I found a download of Rebol 1.0.2, which I could extract with the following commands on a modern Debian Linux:
$ sudo apt install rpm2cpio
$ rpm2cpio rebol-1.0.4-2.i386.rpm | cpio -idmv
I can't get it to run at the moment, but there's HTML files in the archive. Because there's already a sunk cost to backing up the forum, I did some ad-hoc conversion of the HTML to MarkDown and put the Guides up here:
And here's a little bit of analysis of what code we do have:
Note that I have written some about this here:
Quick Impressions
Usage-wise, Rebol1 looks closer to Rebol2 than I expected. I imagined it being weirder...partially because it had vanished and had something of a lore from Joe saying how different Rebol2 was. But at least from the user's perspective, it looks quite close.
Cynically I'd say: it kind of looks like design of the Rebol language (not counting Ren-C) froze/peaked 26 years ago. The enduring subsequent work seems to be PARSE and VID, vs. the interpreter itself.
Not a whole lot of surprises, but I'll write a few thoughts.
-
Biggest observation: it seems like Joe saw functions as the building blocks of most things, including binding. Remember that Rebol2 trick where COLLECT received a BLOCK!, and inside that block it wanted any references to KEEP to refer to its function that would append to the collected block...so it just said something along the lines of:
keeper: func [item] [append collected item] do (func [keep] body) :keeper ; KEEPER becomes KEEP parameter to BODY
It seems like this is how Rebol1 modeled binding, generally.
That might feel clever, but when the cost of binding is to sequester your structural data away into a black box of a function...then you've lost the currency of the parts that comprise the lists. The value proposition of Rebol falls off quickly if your solution is made by isolating everything into information-hiding functional parts. If anything, it's reliant on information-showing and maximizing the value of that.
I can get why Carl wanted to move away from something that was more lambda calculus than it was LEGO. An alternate way of thinking is needed--in particular regarding binding--but just not a patently naive approach, which is what happened.
-
There don't appear to be any datatype specs in Rebol 1.0. All arguments accept all types, it seems...and any type checking has to be done inside your function. That's pretty rough (though it was quite the struggle to break free of the 64-type limit with a solution that performed at all well).
-
We know that MAKE used to have variable arity, e.g.
make function! [spec] [body]
vs.make object! [def]
. Rebol2 did something weird withmake function! [[spec] [body]]
while Ren-C just said "why not have an arity-2 FUNCTION native"? -
It's strange to find out that the counterpart to NEXT was PAST instead of BACK (though the documentation also mentions BACK, so perhaps they were synonyms?) The bigger question remains whether these should be next of and back of, to let
next
andback
be freed up for variable names. -
Interesting to see the
use [[vars] <code>]
syntax instead ofuse [vars] [<code>]
. I've always been baffled by the lack of discussion of tradeoffs in dialect design--why you would make one choice vs. another...so changes like this are actually much more rare than one would think. -
To me, it's good to see ELSE in Rebol 1.0... as I think it's a comfortable and human thing in terms of the rhythm of conditional logic. The implementation was wrong, but Ren-C has solved that with a generalized evaluative pattern that isn't a "hack". It's become kind of amusing to me that some devout Redbol people think ELSE is a sin, and everyone should love EITHER for all situations.
-
The idea that you pass CATCH the WORD! you want to act as the "throw" is how Ren-C's definitional CATCH works (it defaults to THROW, but you can override it). It's called a "continuation" but I wonder just how generic it is...can these continuations do weird stuff, like goto?
goto: none catch 'throw [goto: :throw] print "Will this print twice?" goto <whatever>
Ren-C's CATCH is not based on continuations--just throwing up the stack--so it won't do that. You need to use GENERATOR and YIELD if you want to do continuations.
Anyway... I may have a test or two to throw at it if someone gets it to run. But I don't think there's anything particular for Ren-C to learn from it, things are... quite far along the road.