Documention for: tower.r Created by: btiffin on: 12-May-2007 Format: text/editable Downloaded on: 30-Apr-2025 [h1 Usage document for %tower.r [contents [numbering-on [h2 Introduction to %tower.r [p Wow! This script highlights REBOL's **data is code** and **code is data** principle in a most humorous yet serious way. [h2 tower At a Glance [p This script can be run right out of the box. I won't spoil the surprise by showing any output here. [h2 Using %tower.r [h3 Running %tower.r [p This script is simple to use. Just <strong>DO</strong> it. [asis >> do %tower.r asis] [p This space intentionally used up to alleviate the table of contents from covering pertinent information. [p To run this directly out of the rebol.org library [asis/style/font-size:75% >> do http://www.rebol.org/cgi-bin/cgiwrap/rebol/download-a-script.r?script-name=tower.r asis] [h2 What you can learn [p There is **a lot** to learn inside this little gem. [h3 The REBOL documentation [p As we dig in, you make want to refer to [table/att/border="1px" [row [cell The REBOL Core Manual [cell [link http://rebol.com/docs/core23/rebolcore.html "The REBOL Core Manual" [row [cell The Function Dictionary [cell [link http://rebol.com/docs/dictionary.html "The REBOL Function Dictionary" [row [cell The Viewtop Word Browser [cell as well as the very handy Viewtop tool, **Word Browser** table] [p 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. [p If you invoke REBOL/View and it starts in console mode, type [asis >> desktop asis] to get to the Viewtop. Kinda of misnomer command, but hey. [p Now back to %tower.r [h3 Starting with use **use** allows for local definitions within an evaluated block. [h3 set-words and get-words [p In the REBOL lexicon, [link http://rebol.com/docs/core23/rebolcore-4.html#section-5.3 "set-words" umm, set words and [link http://rebol.com/docs/core23/rebolcore-4.html#section-5.4 "get-words" well, get the value of a word, without evaluating it. Check the links for a more detailed explanation. [p 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**. [h3 copy [p **plain-words** is first set to an empty block. More precisely, it is set to a **copy** of an empty block. See [link http://rebol.com/docs/core23/rebolcore-6.html#section-5.3 "Initial copies" for why. [p Then **plain-words** is built from the **block-of-words** block. Here we get to see the simplicity of block! values in action. [h3 foreach [p 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. [h3 insert tail [p 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**. [h3 paren , group REBOL words. [p 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 [link http://rebol.com/docs/core23/rebolcore-16.html#section-2.9 "paren". [h3 either [p Inside the paren expression is an **either** function that is like the if-then-else of other, lesser languages. [h3 tick symbol [p Then we bump into a tick symbol, or apostrophe word. It's deep, but again, I'll let the manual explain [link http://rebol.com/docs/core23/rebolcore-4.html#section-5.2 "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. [p 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). [asis >> help newline NEWLINE is a char of value: #"^/" asis] [p 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. [p So...in this short example, we have [table/att/border="1px" [row [cell newline [cell the word in the block-of-words [row [cell 'newline [cell the literal word to compare the variable **word** to [row [cell :newline [cell the get-word, returning that **#"^/"** thingy table] [h3 mold [p And finally, in this cool little **foreach** loop, if the **word** is not a literal 'newline, then return the **mold**ed **word**. The **data is code** and **code is data** principle at work. [p Once again, the manual does a fairly round about definition of [link http://rebol.com/docs/core23/rebolcore-8.html#section-2.5 "Mold". [p Now we go on to the next sequence. [h3 blocks of blocks [p 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. [p Skimming over this, down to **Bombastic**, where we get to some more **"splain'in to do"** [h3 reform [p **reform** reduces and forms a block. See [link http://rebol.com/docs/core23/rebolcore-8.html#section-2 "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... [h3 pick [p **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 [link http://rebol.com/docs/core23/rebolcore-6.html#section-1 "Series". [p 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 [link http://rebol.com/docs/words/wpick.html "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... [h3 random [p 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. [p In this case, the **pick random [...] 3** sequence, tells REBOL that it should return one of the three strings in the block...at random. Too cool. [p 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**. [h3 setting words with set [p Next, inside the Bombastic block, we encounter [asis set [differently different] ["alternate ways" "various"] asis] [p 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""]. [p **differently** is set to "alternate ways" and **different** is set to ""various"". [h3 Still here? [p If you made it this far, we only have the example left to explain. This not so short explanation is well worth the read. [h3 example [p 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. [h3 What is in example [p This is a pretty neat little block of code. [p 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. [p Then the block-of-words is printed out, using **print**. This lets us see the story as plain words. [h3 forskip [p 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**. [br See the [link http://rebol.com/docs/core23/rebolcore-6.html#section-6.4 "forskip" entry in the manual. [p 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. [p Anyway, we now see [asis do second ways-to-speak asis] [p This tell REBOL to run the code in the **second** part of the current index in **ways-to-speak** block of named blocks. [p 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. [p The **friend:** set-word changes the variable **friend** to mean "city slicker" and so on. [p 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.) [p 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?** [p 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. [h3 Almost ""done"" [p 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"". [h3 The console [p When you [asis >> do %tower.r asis] [p it will print out the stories, and then [asis == "done" >> asis] [p because the REBOL console, is set up to display the last result. **example** returned ""done"", the %tower.r script ends with [asis do example asis] [p 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"". [h3 And we are ""done"" [h2 What can break Nothing to break here. [h2 Credits [table/att/border="1px" [row [cell %tower.r [cell Original author: Unknown table] [list [li The rebol.org Library Team [li Usage document by Brian Tiffin, Library Team Apprentice, [date list]