Logo isn’t just all about the turtles! When Logo was first being developed, there were no graphical displays — output was simple text on teletypes, which printed out interactions with the computer on paper. When the developers of Logo went into classrooms to test out their invention on students, all they had were teletypes.

As a result, the first Logo ‘microworld’ was the language microworld, not the geometry microworld which is more often associated with Logo. Logo was designed with many powerful commands used to manipulate strings and lists. Logo is based on Lisp, which stands for List Processing, a programming language in which data and code are the same, and are interchangeable and manipulatable by the running program. In Lisp, as in Logo, programs can modify, create and run themselves.

Some of these primitives (commands) include:

word – join two pieces of text together, eg word “dog “cat returns “dogcat

list – take two words and form a list, eg list “dog “cat returns [dog cat]

first, second, third, last – returns the appropriate character (word0 or item (list)

item, setitem – retrieve or change an item in a list or word based on its numerical index

fput, lput – returns a copy of a list with an additional item inserted in the front or back

butfirst, butlast – returns a list without the first or last item

leading, trailing – returns the front and back of words, respectively

push, pop, queue, dequeue – add or remove items on to the front or back of lists

There are also primitives that sort and search, retrieve words from a built-in English dictionary, convert characters to ASCII and back, and much more. You can browse them all in the Words and Lists reference.

So what can we do with all of these wonderful, powerful tools? Here’s a few examples:

Output

While we can manipulate strings and lists internally we still need to output the result to the user. In Logo, this can be done using the show, print and type primitives, and in turtleSpaces you can additionally typeset (create graphical text) or say (text-to-speech) them.

This example uses the print and the pick commands, the former types text into the console (text) area, following it with a line feed (carriage return) while the latter chooses (picks) a random item from a supplied list. In the example, this is used to generate a randomized simple story:

Note that a ‘word’ in Logo is a single word, usually represented with a single double quote, eg “frog

Multiple words can either be represented in a list, eg [dog cat pig], or as a phrase |fat dog|, or both [|fat dog| |lazy cat| |pink pig|]

In the case of the last example, the second item in that list is |lazy cat|. You can turn |lazy cat| into a list of two items using the parse primitive.

A one-line version:

Questions and Answers, Repeats and Repcounts

The next example takes a user-supplied string and turns it into a word pyramid, by repeatedly displaying more and more of the word on successive lines.

It does this first by retrieving the desired word from the user using the question primitive, which prompts the user for input and then ‘stores’ the result in the ‘answer’ primitive, a function that returns the user’s input.

Then, it determines the length of the word using the count primitive, and employs repeat and repcount to generate the pyramid. repcount returns the current iteration of a repeat loop and is a very useful primitive.

reverse is also used in this example, which reverses a word or list.

Word(s) around the world!

The turtle is starting to get a bit bored, so let’s give her a bit of a workout! The next example uses the typeset and orbit primitives to create a ‘word circle’ out of user-provided input.

The orbit commands in turtleSpaces allow the turtle to orbit around a specific point in turtleSpace. We’re going to use the item primitive and a bit of math to distribute the input into a ring around the home [0 0 0] point:

Spiral Stories

Similarly, this next example creates a spiral of words, which grow larger over time as the spiral is built. Each word is spoken by the computer’s text-to-speech facility. Rather than prompting for input, the ‘story’ is defined in a container (variable) using the make primitive.

While in the previous example, item was used to pick out each letter in the user’s input, here it is used to pick out each list item (word) in the “message (story) container.

The foreach primitive is used to typeset each letter in each word independently, to create a more flowing effect. This example demonstrates opportunities for creating text-based animations and artworks:

Codes and Cyphers

Whew! Myrtle’s had her workout, so she can take a well-deserved rest now. Let’s look at some fancier text manipulation, starting with a simple cypher.

Cyphers traditionally manipulate each letter in words in a specific, usually secret way, so that one can pass messages without those who intercept them having the ability to read them.

In the case of our simple example, we’re going to advance the ASCII value of each character by one, changing A into B and so-on.

This procedure is also our first encounter (in this article anyhow) with the “functionalisation” of a procedure in Logo.

In Logo, a procedure can either be just a procedure, in the sense that it is executed simply by declaring its name, and nothing more, or it can be a function, which requires input values be provided when it is declared, such as forward 20. It can also be a returner, which returns a result but requires no input, or a functional returner, which takes input and returns a result.

clearscreen – procedure
forward 20 – function
pencolor – returner
sin 20 – functional returner

Our cypher is a functional returner: it requires an input while returning an output. As a result, it needs to be executed by feeding it back into something else, such as print:

print cypher “albatross

This cypher example only encrypts a single word, or phrase if input is provided using the pipe symbols:

print cypher |I wish I was a secret agent!|

Now, as to the code itself, it first uses a boolean (listp) to check if the input is in fact a word / phrase and not a list, and complains if it is not. Booleans (predicates, which is why they typically end with p) return true or false, based on the input they are provided or the state of the turtleSpaces environment. The ‘if’ primitive takes a boolean result and if it is true then executes the supplied list.

See what I mean when I say lists of data and code are the same in Logo? You can manipulate lists of code just like any other list, and attempt to execute any list (although the results may not be that useful!)

Next we create an empty output container, and then foreach character in the input, we convert it to its ASCII value, add one, and then convert it back into a character, inserting it into the output container. Finally, we use the output primitive to return the result back to the calling primitive, for example print.

Deciphering the Gibberish

Of course we need to decipher our encrypted messages too:

The Language of Music

Of course, English isn’t the only language Logo can speak — it can speak all sorts of languages! But especially, it can speak the language of music, using the playnotes primitive.

playnotes takes a list of music ‘commands’ and then plays them. These include:

L# – play the next provided note at the given length. L0 = 16th note … L9 = double whole note!

R# – plays a ‘rest’ (no tone) of the given length (similar to L)

C5 – plays a note of the given tone (C) and length (5)

Can we use list primitives to create random music? You bet we can!

This example uses the forever loop to play randomly generated music… forever! Inside the forever loop the code employs the list, word, pick and random primitives to piece together our computer-created composition:

Note how we can use the () round brackets to spread out a single complete instruction across multiple lines to make it easier to comment and read.

Doyay owknay igpay atinlay?

Pig Latin is a perennial favourite of children across the ages. A series of simple rules are used to create a ‘secret language’ that can only be understood by those who know them.

The rules are:

  1. If the word only has one letter (a) leave it as-is
  2. If the word only has two letters, add ‘yay’ to it
  3. If the world starts with ‘th’, move it to the end and add ‘ay’ to it
  4. If the word starts with a vowel, add ‘nay’ to it
  5. Otherwise, move the first letter to the end and add ‘ay’ to it.

The following example uses if, elsif and else to sort the input words through all of these rules, stitching together a result:

Note the use of the leading and trailing primitives, which return the front and back of input words, respectively.

And now for something (somewhat) completely different…

You know that you can make containers containing values, and that you can use expressions to create those values. Typically these expressions are evaluated before they are put into the container, and so they are fixed at the point in time the make is executed. But what if you could put the expression into the container instead? This is where make! comes in handy:

As you can see from the example, containers created with ‘make!’ are more like magic boxes, whose contents change based on when you look inside them. Logo is magical, indeed!

A Sophisticated Story

Earlier, we told a simple story, now let’s tell a more sophisticated one.

In the following example, a series of list containers are created containing various story elements. These elements are then laid out on the graphical display using the typeset primitive. Note the absolute positioning set using the setxy primitive.

This is actually a fairly simple example, with the opportunity for participation from the entire classroom, in choosing the various words and phrases that make up the story:

And they lived happily ever after.

The next word, and the next word…

This next example is a simple little cracker, which uses the english primitive to retrieve random words from turtleSpaces built-in English dictionary, and then typesets them into the graphical display, rolling and turning the turtle to create a 3D ‘word cloud’.

If you click and drag on the graphical display area you can rotate around the output.

If you are unable…

The next example tries to pick a random word out of the dictionary and turn it into an un-able variation, eg unfixable.

A naive version would look something like:

print (word “un pick english 5 “able)

which while straightforward is going to output a lot of rubbish.

Like piglatin, we’re going to define some rules that we’ll use to process the word and see if we can create something that makes sense. But this time we’re going to do this through exclusion — if the random word doesn’t conform to our rules, we will simply pick another one.

We’ll do this using the dountil primitive, which does something until specific conditions are met:

Is this cheating? We’ll leave that for you to decide.

Check out these and other examples in the following turtleSpaces project:

turtlespaces.org/weblogo/?pub=193