On J.R. Carpenter’s Gorge, Part Two: Choosing the Words


This post is the second in a series on digital literature. I’m dissecting the JavaScript code of “Gorge”, an infinite poem by J.R. Carpenter that riffs on Nick Montfort’s program “Taroko Gorge”.  The first post, which defines “variables”, “strings” and “arrays”, is here.

At the end of the last post, I said that we would continue by looking at how to choose a substring from an array, and what happens from there. In order to understand how the program selects a substring, you have to understand something else first: what a function is, and how it works within a program.

It’s hard to meaningfully define a function in non-technical terms because it is so basic a thing that breaking it down further is difficult; at the same time, too vague a definition will be imprecise and therefore meaningless. The best I can do for you right now is to say that functions are basically chunks of code that, as the name might suggest, do something. When you call a function, you’re invoking the code in it. If similes are your thing, you could say that calling a function is like casting a spell: you can have the spell written down, but it doesn’t do anything until you bring it into existence.

Functions have names, arguments, and bodies. This is probably best illustrated by actual code:

 function rand_range(max) {
   return Math.floor(Math.random() * (max+1));

The name of that function is rand_range, the argument that we pass to it is max, and the second line (beginning with the word return) is the body of the function. It is, in other words, what the function will do, when it is called, with the argument max. max, as you may have guessed by now, is just a variable representing a maximum value. If we say that max is 3, the function will execute with 3 taking max‘s place.

What does that mean, practically speaking? What will the function actually do when called? Its name should give you a clue: looking at something called rand_range, it’s a safe bet that it’ll have something to do with a random number that falls within a predetermined range. Add the fact that the argument has been named max, and you can further guess that the value of max represents the top end of that predetermined range. Now all you have to contend with is Math.floor and Math.random. Math.floor is a function (functions can call each other) that returns the largest integer less than or equal to a given number (in this case, max); Math.random returns a pseudo-random (which is to say, more or less random for most purposes but not strictly random, since that’s pretty hard to achieve) integer between 0 (inclusive) and 1 (exclusive). You can scale that up or down; in the event that max is 3, as I suggested earlier, Math.random returns an integer between 0 and 3, not including 3. This is why the function includes (max + 1), which extends our range by 1, allowing us to include 3.

The next function is called choose. It exists in order to produce a random selection from the arrays that we discussed earlier, the ones like above (“appetite, brain, craving, desire”), below (“aroma, bladder, blood vessel, bowl”), and trans (“agitate, attract, bite, boil”). choose looks like this:

 function choose(array){
   return array[rand_range(array.length-1)];

When you insert the name of an array—let’s say above[rand_range(array.length-1)] selects a random value from that array. (The -1 bit is there because the first thing in an array is denoted Thing 0. Computers like to start counting at 0. So -1 just means that you get the whole range of the array from the first (zeroth?) item to the last.) Then return array returns the index that’s been selected. So if we were to do this with above, the index might be, e.g., 3, which would return ‘digestive juice’ (since we’re counting from 0, remember!)

The next function is where we start to get into the actual construction of the poem, and it’s followed by two other functions that are very similar. These functions haven’t been renamed since their inception as part of Taroko Gorge, so they may at first glance appear irrelevant to the content of Gorge, but they’re doing the right things. There’s a section in the middle of this first function that doesn’t work in Gorge, which you’ll probably be able to spot straight away. It doesn’t do anything bad; it just doesn’t get evaluated.

 function path() {
 var p=rand_range(1);
 var words=choose(above);
 if ((words=='forest')&&(rand_range(3)==1)){
   words='monkeys '+choose(trans);
 } else {
   words+=s[p]+' '+choose(trans)+s[(p+1)%2];
 words+=' the '+choose(below)+choose(s)+'.';
 return words;

And breathe.

var p is defined as rand_range(1), which we know means “a random whole number between 0 and 1”. Practically speaking, that means “either 0 or 1”. We don’t know what we’ll be doing with var p yet, so we’ll just put that away for later use.

var words=choose(above), as we know from our adventures with choose(array) previously, means that words is set to a random selection from the list of words in the array above.

The if statement says that if the value of words happens to be “forest”, and if the rand_range value is 1 (with the max value defined as 3, so the value could be 0, 1, 2 or 3), then “forest” will be replaced with the word “monkeys” and a random selection from the transarray. Since we don’t have the word “forest” in any of our arrays, this piece of code will actually never be used. It’s a leftover from Montfort’s original version.

else means “otherwise”, so this is where we can start paying attention again: if the conditions of the if statement are not met (and they won’t be), this is what will happen next.

words+=s[p] is a random pluralizer. It takes a var from earlier up in the program, which I realize now I may have skated over somewhat in the first post. This is s, which is defined as 's,'.split(','). What this means is that s is actually another array, split on its comma, so that the array consists of the letter ‘s’ and nothing, known in programming as ‘the empty string’. Therefore, words+=s[p] means that when p=0, s will be added on to the end of whatever value we got from words. (words+=s[p] is a short-hand for words=words+s[p]. “Adding” a string means that it is glued on to the end of whatever comes before.) As we start counting from 0, that means a letter ‘s’ will be added, making the word plural. When p is 1, the second element of the array s will be added to the end of words, which in this case means nothing at all.

After this will come a space (signified by ' '), no matter whether the value of var words has been pluralized or not. Then a word will be selected from the trans array, which will be pluralized half of the time. This is signified by (p+1) % 2, where % means “the remainder after division by”. Cast your mind back to elemento-primary school! When p is 0, we get 0+1, which is 1, and the remainder of 1 divided by 2 is 1. We’ll add element 1 of array s again, which is empty string. When p is 1, we get 1+1, which is 2, and the remainder of 2 divided by 2 is 0, so we’ll append the first element of array s (remember, the first element is element 0!), which is the letter ‘s’.

The final section has the addition of the word ‘the’ to whatever comes out of words, a random selection from the array below, a random selection from the array s (another choice between pluralizing or not), and the addition of a full stop. return words is the piece of code that will actually return the value for function path(), when it’s called.

More next time, including a couple of other functions that select words from arrays using different criteria, and the beginnings of how the program fits all of these functions together to produce the poem itself.


3 thoughts on “On J.R. Carpenter’s Gorge, Part Two: Choosing the Words

  1. Oh I forgot about this! Too bad the forest part doesn’t work. For some reason the thought of forest being changed to monkeys tickles my funnybone. You are very good at explaining the programming. Are you a programmer or teacher in non-blog life?

    • No, I’m not, so thank you very much for the accolade! My boyfriend is a programmer, though, and I am new to the topic, so I try to explain things in ways that a) I think I would understand, or b) have already worked while he’s been explaining things to me. (He also proof-reads these posts to make sure that nothing is misleading or inaccurate, so part of the clarity is down to his sharp eye!)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s