Script Library: 1227 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

Documentation for: tower.r

Usage document for %tower.r

1. Introduction to %tower.r

Wow! This script highlights REBOL's data is code and code is data principle in a most humorous yet serious way.

2. tower At a Glance

This script can be run right out of the box. I won't spoil the surprise by showing any output here.

3. Using %tower.r

3.1. Running %tower.r

This script is simple to use. Just DO it.

 >> do %tower.r

This space intentionally used up to alleviate the table of contents from covering pertinent information.

To run this directly out of the library

 >> do

4. What you can learn

There is a lot to learn inside this little gem.

4.1. The REBOL documentation

As we dig in, you make want to refer to

The REBOL Core ManualThe REBOL Core Manual 
The Function DictionaryThe REBOL Function Dictionary 
The Viewtop Word Browser as well as the very handy Viewtop tool, Word Browser

You get to the Word Browser by starting up REBOL/View Viewtop clicking the top left REBOL folder, clicking the Tools toolbox icon and the the Word Browser toolbox icon. The first time you execute this utility, it will prompt for permission to download the dictionary, and then (and from then on) opens the Word Browser.

If you invoke REBOL/View and it starts in console mode, type

 >> desktop
to get to the Viewtop. Kinda of misnomer command, but hey.

Now back to %tower.r

4.2. Starting with use

use allows for local definitions within an evaluated block.

4.3. set-words and get-words

In the REBOL lexicon, set-words  umm, set words and get-words  well, get the value of a word, without evaluating it. Check the links for a more detailed explanation.

Inside the use block, the first thing is to set the story. block-of-words is set to a block of words making the original wording, with a special symbol at the end of each line. Next, another set-word is used to define plain-words.

4.4. copy

plain-words is first set to an empty block. More precisely, it is set to a copy of an empty block. See Initial copies  for why.

Then plain-words is built from the block-of-words block. Here we get to see the simplicity of block! values in action.

4.5. foreach

So, for each word in the block of words, so succinctly coded in REBOL as foreach word block-of-words, add each word to plain-words, with a little REBOL magic thrown in.

4.6. insert tail

This is a little weird, but in early REBOLs, prior to R3, insert tail is/was just a fancy (yet much faster) way of calling append. So for now, just read the insert tail as append.

4.7. paren , group REBOL words.

After the insert tail is a paren! expression. Paren is short for parenthesis. The ( and ) symbols. I'll leave it to the Core Manual to explain paren  .

4.8. either

Inside the paren expression is an either function that is like the if-then-else of other, lesser languages.

4.9. tick symbol

Then we bump into a tick symbol, or apostrophe word. It's deep, but again, I'll let the manual explain Word usage  for the meaning behind the use of the 'newline expression. In short it means: don't evaluate newline, just use the symbol (or string, but it's not a string, it is the word) newline . Clear as mud? It was for me at first and don't worry, it will sink in.

So if word (the variable) is the literal newline , add a line break to the story in plain-words. How? By getting the value of the newline variable, which just happens to be the character that prints a line break, (or carriage-return and line-feed in the old typewriter days).

 >> help newline
 NEWLINE is a char of value: #"^/"

This is done with a get-word sequence by placing a colon in front of the newline symbol. Yeah, this is real clear isn't it, but oh man, is it powerful when programming REBOL. this short example, we have

newline the word in the block-of-words
'newline the literal word to compare the variable word to
:newline the get-word, returning that #"^/" thingy

4.10. mold

And finally, in this cool little foreach loop, if the word is not a literal 'newline, then return the molded word. The data is code and code is data principle at work.

Once again, the manual does a fairly round about definition of Mold  .

Now we go on to the next sequence.

4.11. blocks of blocks

Next is another set-word that defines ways-of-speaking, that just happens to be a block of blocks with a bunch of set-words.

Skimming over this, down to Bombastic, where we get to some more "splain'in to do"

4.12. reform

reform reduces and forms a block. See Converting Values to Strings  and read section 2.1 to 2.6 for more information, but basically reform, forms a block of values into a string. Which, in this case leads to the series! operation...

4.13. pick

pick is an index accessor for any series. The series concept pervades REBOL. Meaning that this concept is everywhere in REBOL. Just about everything is a series. Once again, the fine manual does its best to explain Series  .

But back to pick. The pick operation accepts a series and an index as arguments. This means, give me the value in the series at index. Read pick  in the Function Dictionary for more information. It is kind of like random access in lesser languages. I didn't want to use the expression random access because the next operation in the %tower.r script that I'll try to explain is...

4.14. random

In REBOL, random is one powerful little operator. You can call random on all sorts of things. Numbers, strings, blocks, tuples, dates,..., dang near anything.

In this case, the pick random [...] 3 sequence, tells REBOL that it should return one of the three strings in the random. Too cool.

Oh yeah, then it appends the literal word block . In this case the actual word block. Having nothing to do with blocks, or block data, just the word block.

4.15. setting words with set

Next, inside the Bombastic block, we encounter

     set [differently different] ["alternate ways" "various"]

This sequence is another form of set-word, but in this case we are setting two words, differently and different to the values in the block ["alternate ways" "various"].

differently is set to "alternate ways" and different is set to "various".

4.16. Still here?

If you made it this far, we only have the example left to explain. This not so short explanation is well worth the read.

4.17. example

This script now defines a block (set-word example) that is a code block. REBOL doesn't care what you put in a block but this example block will be evaluated with do. Then REBOL cares, because do tells REBOL to run the code in the block. The proper REBOL expression for this is evaluate, but it can be referred to as 'run', 'do' or 'execute' and other REBOL programmers will know what you mean.

4.18. What is in example

This is a pretty neat little block of code.

First it sets block-of-words to the newly built plain-words, with the newline symbols replaced with the #"^/" thingy that prints a line break.

Then the block-of-words is printed out, using print. This lets us see the story as plain words.

4.19. forskip

This forskip operation tells REBOL that you want to loop over all the values in a series, skipping over some of them. In this case, start at the first value in the ways-of-speaking block of blocks, Hill-billy then the third, Sales-speak, then the fifth Angry and finally the seventh Bombastic.
See the forskip  entry in the manual.

Now, something tricky again. The series! ways-of-speaking is being looped over with forskip. Internally REBOL is keeping track of this with a series index. You don't even know where this index is stored, but REBOL does. Not to worry. REBOL knows.

Anyway, we now see

 do second ways-to-speak

This tell REBOL to run the code in the second part of the current index in ways-to-speak block of named blocks.

The first time through the loop, this will execute all the set-words in the Hill-billy block. Data is code and code is data. It turns out that the set words in the Hill-billy code block change the meaning (redefine) all the plain words into the Hill-billy words. The Hello: set-word changes the variable Hello to mean "Howdy". When the plain-words block was built, the Hello variable was set to the molded value of itself, and was "Hello". Data is code.

The friend: set-word changes the variable friend to mean "city slicker" and so on.

Then the block-of-words is reprinted, with its own title. first ways-of-speaking is the literal word Hill-billy and prints out as "Hill-billy". Code is data. (Well in this case data is data, but you know what I was going for.)

Now when you print block-of-words it reforms all the words in the block and you end up with Hill-billy speak. How cool is that?

The inside the forskip loop, the block-of-words is reset back to the plain-words and the next iteration will set all the plain words to Sales-speak, which will be evaluated, and printed. Then through Angry and Bombastic.

4.20. Almost "done"

The example code block ends with the string "done". This demonstrates the REBOL return value. The example, after printing all the different speeches, will return "done".

4.21. The console

When you

 >> do %tower.r

it will print out the stories, and then

 == "done"

because the REBOL console, is set up to display the last result. example returned "done", the %tower.r script ends with

 do example

What this means is, %tower.r returned it's result which just happens to be the result that was returned from do example, or done in this case, and the console, sensing that your last command input is finished, dutifully displays the last result, "done".

4.22. And we are "done"

5. What can break

Nothing to break here.

6. Credits

%tower.r Original author: Unknown
  • The Library Team
  • Usage document by Brian Tiffin, Library Team Apprentice, Last updated: 12-May-2007