Chapter 10: Words, Lists and Numbers

Logo data consists of characters that can be combined to make words and lists. Sounds too simple, doesn't it? In one sense, all Logo data is just characters. However, Logo interprets sequences of characters as different types of data, depending on the characters used. In fact, so do you. You interpret the sequence 100 as the number one hundred - a numeric value. To Logo, the sequence 100 is a three-character word. A word that can be interpreted as a numeric value can be used as a number. Usually, a word needs a double quotation mark in front of it. However, Logo allows you to forget about the double quotation mark when you enter a number - it's like a hidden shortcut because Logo knows that people do not think of numbers as words. And, there are certain manipulations that can be done to numbers that are not valid for words. For these reasons, numbers are covered in their own section.

As you work your way through the following sections, you will notice that some of the same commands are used more than once. Many of the commands for words also work with lists. And, since numbers are special words, some of the commands work for numbers, too. Each section is written specifically for each type of Logo data so that the examples and explanations in each section are consistent with the type of data. You'll find that having commands that work equally well with either words or lists is very convenient. Learning how to use the commands for words is best done with words only. It avoids any specific qualifications for using them with lists and helps to keep you focused on how words are affected.

Computing with Words

Most words in Logo are no different than what you think of as words. A space tells you that a word has ended and the same is normally true for Logo. You also use special punctuation characters that show the end of a word, but they are not considered to be part of the word - like the comma, for example, or the period at the end of a sentence. In Logo, a period or comma is just another character.

Sometimes, you put a word in quotes to make it appear “special” - it's still a word but it stands out from the rest. In Logo, there are special characters that are not normally part of a word because they usually have a special meaning. If you want to use a special character as a regular character, you have to use the backslash character to tell Logo to ignore the special meaning. For example, the space character usually separates words, but you can include a space if you want. Type:

```PRINT "A WORD WITH SPACES
A WORD WITH SPACES```

The one character immediately following the backslash is treated as a regular character. In this case, the spaces are not separating one word from another - the spaces are part of the word that is printed. Without the backslash, the space is treated as a normal word separator. Type:

```PRINT "A WORD WITH SPACES
WITH is neither a procedure nor a name```

Another way to “escape” the special meaning of special characters is to use the vertical bar characters - one at the beginning and one at the end. For example, type:

```PRINT "|A word with spaces|
A word with spaces```

You still need the double quotation mark to tell Logo that a word follows. The vertical bars not only allow special characters to be part of the word, but they also prevent Logo from changing the characters to uppercase. Character sequences enclosed in vertical bars are called “strings” of characters, but they are still words to Logo.

What if you need to use a backslash or a vertical bar as a regular character? You have to put a backslash in front of it. That means it takes two backslashes to get one backslash. Type:

```PRINT "BACKSLASH
BACKSLASH

PRINT "VERTICAL|BAR
VERTICAL|BAR```

The backslash and vertical bar characters are useful, and sometimes necessary. If you want to quote a word, for example, you can use one or the other. Type

```PRINT "|"quote"|
"quote"

PRINT ""quote"
"QUOTE"```

Don't let these unusual forms of words bother you. Just be aware that there are special times when special characters are used in special ways for special purposes.

Most of the words you've used so far were complete words that you typed in. There are times when it's necessary to use just a part of a word and then there are times when you need to take the parts and put a word together. There are Logo commands to put words together and other commands to take them apart. However, none of these commands actually change anything. You can use the results of these commands in any way that you would use words that you type - print them, use them as names, or assign them to variables. Comparing one word to another can be important for making decisions. Knowing more about words can make your Logo experience more fun.

Taking Words Apart

Just so you can see that taking a word apart does not change it, enter the following command to create the `:SAMPLE` variable with the value `FLOWERS`:

`MAKE "SAMPLE "FLOWERS`

The `FIRST` command outputs the first element of the word you give it as input. Each character is an element, or member, of the word. Type:

```FIRST :SAMPLE
Result: F```

The output of `FIRST` is just the character F - the first element of the word `FLOWERS`. The value of `:SAMPLE` was only used as input to the `FIRST` command. Type:

```SHOW :SAMPLE
FLOWERS```

None of the commands that take words apart actually change the input word. The output of these commands is made up from copies of the parts of the input. If you want the value of a variable changed, you have to use `MAKE`. For example, type:

```MAKE "SAMPLE FIRST :SAMPLE
SHOW :SAMPLE
F```

Now, `:SAMPLE` has a new value which is the same as the first element of its original value. The rest of the examples will use the literal word as input rather than a variable - it's easier to follow what's going on that way.

Another way to get the first element of a word is with the `ITEM` command. It needs two inputs: the number of the element you want and the word from which to get it. Type:

```ITEM 1 "FLOWERS
Result: F```

The result is the same as with `FIRST`, which is really just an abstraction of `ITEM 1`. `ITEM` can be used to get any element of a word, from the first to the last. It can be handy because there are no commands called `SECOND`, `THIRD` and so on.

Many Logo commands do the opposite of another command. The `LAST` command outputs the last element of the word you give it as input. Type:

```LAST "FLOWERS
Result: S```

The `ITEM` command returns the last element if you give it the number of elements. Type:

```ITEM COUNT "FLOWERS "FLOWERS
Result: S```

The result is the same as with `LAST`, but it's much easier to use `LAST`.

`FIRST` and `LAST` output a single character. Sometimes, it's useful to get the rest of the word they leave behind - either all but the first element or all but the last element. Logo has two commands that do just that - `BUTFIRST` and `BUTLAST` which have the shortcuts `BF` and `BL`. Type:

```BUTFIRST "FLOWERS
Result: LOWERS

BUTLAST "FLOWERS
Result: FLOWER```

You can remove all occurrences of one word from another word with `BUTMEMBER` (`BM` for short). It takes two words as input and outputs the result of removing the first word from the second word. This may seem to be an odd thing to do, but a word can be just one character. Type:

```BM "E "BEEKEEPER
Result: BKPR```

If the first word is more than one character, then all occurrences of the sequence of characters are removed - not the individual characters. Type:

```BM "KEE "BEEKEEPER
Result: BEEPER```

The `FROMMEMBER` command (`FM` for short) takes two words as input. It finds the first occurrence of the first word in the second word and outputs the characters from that point to the end of the second word. Type:

```FM "E "BEEKEEPER
Result: EEKEEPER```

The first word can be more than one character. Type:

```FM "KEEP "BEEKEEPER
Result: KEEPER```

Sometimes, getting a character at random is useful. You've used the `PICK` command to select random colors from a list, but it works for words, too. Suppose you want to simulate tossing a coin to see if it comes up heads or tails. You could do that with `PICK` and the two-character word `HT` or `TH`. Either way, one of the letters will be chosen at random. Don't bet on which one will show up. Type:

```PICK "HT
Result: H```

You could simulate flipping a coin any number of times and tallying the results in variables named H and T. The `FLIP` procedure takes a number as input and runs the `PICK` command that many times. `PICK` will output either the character H or T and pass it along to `TALLY`. The `TALLY` procedure uses indirect reference with its input word to add 1 to the value of the variable whose name is the input word. The variables H and T are created as local variables in `FLIP`. Because of dynamic scope, `TALLY` has access to them. Define the procedures and then run `FLIP` to see what results you get.

```FLIP 100
50 TAILS```

Putting Words Together

Just so you can see that putting a word together does not change anything, enter the following commands to create two variables:

```MAKE "PART1 "FLO
MAKE "PART2 "WERS```

The `WORD` command normally takes two words as input and combines them to form a new word. Type:

```WORD :PART1 :PART2
Result: FLOWERS```

The output of `WORD` is a new word made from the two parts. The parts are not affected. Type:

```(SHOW :PART1 :PART2)
FLO WERS```

None of the commands that put words together actually change the input parts. The output of these commands is made up from copies of the inputs. If you want the value of a variable changed, you have to use `MAKE`. For example, type:

```MAKE "PART1 WORD :PART1 :PART2
SHOW :PART1
FLOWERS```

Now, `PART1` has a new value. The rest of the examples will use the literal words as inputs rather than variables - it's easier to follow what's going on that way.

A new word can be put together with more than two parts by enclosing the `WORD` command and its inputs within parentheses. Type:

```(WORD "TIC- "TAC- "TOE)
Result: TIC-TAC-TOE```

The `FPUT` command outputs a new word by putting its first input in front of its second input. In other words, the first input is put first in the new word. Type:

```FPUT "FLO "WERS
Result: FLOWERS```

The opposite of `FPUT` is the `LPUT` command. `LPUT` outputs a new word by putting its first input at the end of its second input. In other words, the first input is put last in the new word.Type:

```LPUT "WERS "FLO
Result: FLOWERS```

You can change all occurrences of one word in another word with the `SUBST` command. It replaces all occurrences of its first input with its second input wherever the first input appears in the word you give it as the third input. Type:

```SUBST "E "O "BEEKEEPER
Result: BOOKOOPOR```

The first inputs to `SUBST` don't have to be single characters. Type:

```SUBST "EEK "OOKK "BEEKEEPER
Result: BOOKKEEPER```

The `CHAR` command outputs a one-character word. It needs the ASCII value of the character as input. Sometimes, you may need to use a character that you can't type in from the keyboard. For example, the Carriage Return character has the ASCII value of 13 and causes the cursor to move to the beginning of the next line. Type:

```PRINT SUBST ". CHAR 13 "A.B.C.D.E
A
B
C
D
E```

The Carriage Return character is substituted for the periods. When the result is printed, it may look like five one-character words were printed, but it's really one nine-character word.

Creating new words from parts can be fun. The `PIG.LATIN` procedure creates a new word from four parts. The first part is the `BUTFIRST` of the input word; the second part is a hyphen; the third part is the `FIRST` character of the input word; the fourth part is the syllable AY. Define `PIG.LATIN` and try some examples.

```PIG.LATIN "LOGO
Result: OGO-LAY```

Use `FOREACH` to convert a list of words. Type:

```FOREACH [BIG DOGS DIG DEEP HOLES] [PRINT PIG.LATIN "?]
IG-BAY
OGS-DAY
IG-DAY
EEP-DAY
OLES-HAY```

The `PIG.LATIN` procedure works fine with words that have only one consonant at the beginning. There are more rules to Pig Latin that you can add on your own.

Comparing Words

When you compare two things, you are asking a question. The Logo commands for doing comparisons have a question mark at the end of their names. For example, `WORD?` is a command that asks if its input is a Logo word. The answer (or output) to the question is either the word TRUE or the word FALSE. One way to use `WORD?` is in the `TEST` command. Type:

`TEST WORD? "LOGO`

`TEST` is a rather special command. It doesn't output anything, but it does “remember” the result of the test in a variable called `@COND`. If you want to run some commands when the result of the test is true, you can use the `IFTRUE` command and give it a list of instructions to run. Type:

```IFTRUE [PRINT [YES, THAT'S A WORD]]
YES, THAT'S A WORD```

`IFTRUE` checks the value of `@COND` and if it's TRUE, the instructions in the list are run. The value of `@COND` is not changed until another `TEST` is done. You can put as many `IFTRUE` commands as you want after the `TEST` command. The opposite of `IFTRUE` is `IFFALSE`. Since the current value of `@COND` is TRUE, an `IFFALSE` command at this point would not mean anything. Type:

```TEST WORD? [FLOWER]
IFTRUE [PRINT "SMELL]
IFFALSE [PRINT [ALL'S WELL]]
ALL'S WELL```

A one-word list is still a list - not a word. The `IFTRUE` command does not run its instructions in this example. `IFFALSE` checks the value of `@COND` and if it's FALSE, the instructions in the list are run.

An alternative to `TEST` is `IF`. In one form, `IF` is a combination of `TEST`, `IFTRUE` and `IFFALSE`.

```IF WORD? [FLOWER] [PRINT "SMELL] [PRINT [ALL'S WELL]]
ALL'S WELL```

The first input to this form of `IF` is the same as the input to `TEST` - a condition that returns either the word TRUE or the word FALSE. The `IF` command does not make use of the `@COND` variable; it uses the result of the test to determine what to do next. The second input is the list of instructions to run when the condition is true. The third input is optional, but if you use it, the instructions in the list are run when the condition is false. Another form of `IF` is similar but does not have lists of instructions. Instead, it uses the special words `THEN` and `THEN` as markers. When the test condition is true, the instructions after `THEN` and up to `ELSE` are run. `ELSE` is optional, so the instructions for `THEN` end at the end of the line if `ELSE` is not used. When the test condition is false, the instructions after `ELSE` and up to the end of the line are run. It's more like the way people say things when they make a decision. The following `IF` command is really the same as the example above:

```IF WORD? [FLOWER] THEN PRINT "SMELL ELSE PRINT [ALL'S WELL]
ALL'S WELL```

The form of comparison you use is a matter of personal choice - one way works just as well as another. For more information, look in the online help and the Reference Manual.

The empty word has nothing in it, but it's still a word. You test for the empty word with the `EMPTY?` command. It outputs TRUE if the word is empty and FALSE if it's not empty. If you remove all the characters of a word, you'll end up with the empty word. In the following example, use the up-arrow key and insert additional \$comd[accessors|BUTFIRST] commands after you try each line. Type:

```EMPTY? BUTFIRST "BOX
Result: FALSE
EMPTY? BUTFIRST BUTFIRST "BOX
Result: FALSE
EMPTY? BUTFIRST BUTFIRST BUTFIRST "BOX
Result: TRUE```

Testing for the empty word is necessary when you want to use all of the characters in a word, one at a time. You know you're done when you find the empty word. The `PRINT.DOWN` procedure takes a word as input and prints it, one character at a time. It checks for the empty word in order to know when to stop printing. After the first character is printed, `PRINT.DOWN` is run with a slightly shorter word - the `BUTFIRST` of the original input word. Define `PRINT.DOWN` and then type:

```PRINT.DOWN "FLOWERS
F
L
O
W
E
R
S```

What do you think would happen if you changed `FIRST` to `LAST` and `BUTFIRST` to `BUTLAST`?

A common test in linguistics is whether or not a particular letter is a vowel. The normal vowels are the letters A, E, I, O and U. The `MEMBER?` command takes two inputs and tests to see if the first input is a member of the second input. If a match is found, `MEMBER?` outputs TRUE, otherwise, `MEMBER?` outputs FALSE. The first input does not have to be a one-character word, but that's what you'd need to test for vowels. Type:

```MEMBER? "E "AEIOU
Result: TRUE```

The `PIG.LATIN` procedure you defined earlier should just add the syllable AY to the end of a word that begins with a vowel. Add the following test at the beginning of `PIG.LATIN`.

`IF MEMBER? FIRST :INPUT "AEIOU THEN OUTPUT WORD :INPUT "-AY`

There are more rules to Pig Latin, but this is an improvement-ay? Have you noticed that the usual form of a Logo instruction is the command word followed by its inputs, if it needs any? This form is called prefix notation - the command word comes first. You can do every Logo command this way and it's easy to remember the format. Some command words look more natural if they go in between their inputs. This is called infix notation and the command words are called operators - in fact, most operators are really symbols, like =, <, and >. Logo has both commands and operators for the comparisons: equal, greater than, greater than or equal, less than, less than or equal, and not equal.

All of the comparison operators (represented by symbols) can be used in either a prefix or infix notation. The commands (represented by words) can only be used in a prefix notation. You can often avoid using parentheses to make Logo understand what you are doing if you use prefix notation instead of infix notation. Some examples will show you where parentheses are needed. It's not a big problem, as long as you're aware of it.

To see if two words are equal to each other, you can use either of the commands `=` or `.EQ` or the operator =. Each of the following commands work the same:

```EQUAL? "WILD "WILD
Result: TRUE

.EQ "WILD "WILD
Result: TRUE

= "WILD "WILD
Result: TRUE

"WILD = "WILD
Result: TRUE```

You may need parentheses for the infix notation when the first (or left) input is more complicated than a simple word. It's often a very subtle problem.

```EQUAL? FIRST "WILD "W
Result: TRUE

FIRST "WILD = "W
Result: F```

Result F? What is that? The `=` operator has used the word `WILD` as its first (left) input and compared it to W. Since they were not equal, it output FALSE which was then input to `FIRST` which output the first character of FALSE which is where the F came from. In cases like this, you need to put parentheses around the first input to an infix operator or change the test to have the simple word as the first input.

```(FIRST "WILD) = "W
Result: TRUE

"W = FIRST "WILD
Result: TRUE```

You can reverse the meaning of a test with the `NOT` command. For the prefix notation, just put the `NOT` command in front of the comparison command word or symbol. If you used the infix notation, you can put `NOT` in front of the first (left) input. However, you don't really need to use `NOT` because Logo has all the comparisons you need. It's probably easier and clearer to change the command or operator.

You can read about the rest of the comparison commands and operators in the online help or the Reference Manual. They are an important part of programming. Combined with the `TEST` and `IF` commands, they add a sense of intelligence to your procedures.

Computing with Lists

Most of the lists you've used so far were complete lists that you typed in. There are times when it's necessary to use just a part of a list and then there are times when you need to take the parts and put a list together. There are Logo commands to put lists together and other commands to take them apart. However, none of these commands actually change anything. You can use the results of these commands in any way that you would use lists that you type - print them, assign them to variables and, if they contain commands, give them to the `RUN` command. Comparing one list to another can be important for making decisions. Knowing more about lists can make your Logo experience more fun.

To you, a list of words is a sentence. The same is true for Logo. A sentence in Logo is a special kind of list that contains only words - it can not have other lists as elements.

Many of the lists you have used were actually Logo sentences. But, since a sentence is still a list, it didn't seem worth mentioning. There are times, however, when a sentence is what you want Property lists are another special kind of list. They are discussed in Chapter 6 - Property Lists.

Taking Lists Apart

Just so you can see that taking a list apart does not change it, enter the following command to create the `:SAMPLE` variable with the value `[WILD FLOWERS]`:

`MAKE "SAMPLE [WILD FLOWERS]`

The `FIRST` command outputs the first element of the list you give it as input. The elements, or members, of a list can be words or other lists. Type:

```FIRST :SAMPLE
Result: WILD```

The output of `FIRST` is just the word `WILD` - the first element of the list `[WILD FLOWERS]`. The value of `:SAMPLE` was only used as input to the `FIRST` command. Type:

```SHOW :SAMPLE
[WILD FLOWERS]```

None of the commands that take lists apart actually change the input list. The output of these commands is made up from copies of the parts of the input. If you want the value of a variable changed, you have to use `MAKE`. For example, type:

```MAKE "SAMPLE FIRST :SAMPLE
SHOW :SAMPLE
WILD```

Now,`SAMPLE` has a new value which is the same as the first element of its original value - the word `WILD`. In Logo, a variable can contain any valid Logo data at any time. There is no restriction that the value has to be of the same type of data all the time. Be aware of this - sometimes it can cause problems. The rest of the examples will use the actual inputs rather than a variable - it's easier to follow what's going on that way.

Another way to get the first element of a list is with the `ITEM` command. It needs two inputs: the number of the element you want and the list from which to get it. Type:

```ITEM 1 [WILD FLOWERS]
Result: WILD```

The result is the same as with `FIRST`, which is really just an abstraction of `ITEM 1`. `ITEM` can be used to get any element of a list, from the first to the last. It can be handy because there are no commands called SECOND, THIRD and so on.

Many Logo commands do the opposite of another command. The `LAST` command outputs the last element of the list you give it as input. Type:

```LAST [WILD FLOWERS]
Result: FLOWERS```

The `ITEM` command returns the last element if you give it the number of elements. Type:

```ITEM COUNT [WILD FLOWERS] [WILD FLOWERS]
Result: FLOWERS```

The result is the same as with `LAST`, but it's much easier to use `LAST`.

`FIRST` and `LAST` output a single element. Sometimes, it's useful to get the rest of the list they leave behind - either all but the first element or all but the last element. Logo has two commands that do just that - `BUTFIRST` and `BUTLAST` which have the shortcuts `BF` and `BL`. Type:

```BUTFIRST [WILD FLOWERS]
Result: [FLOWERS]

BUTLAST [WILD FLOWERS]
Result: [WILD]```

You can remove all occurrences of one element from a list with `BUTMEMBER` (`BM` for short). It takes two inputs and outputs the result of removing the first input from the list you give as the second input. The first input can be either a word or a list. Type:

```BM "WILD [WILD FLOWERS AND WILD HORSES]
Result: [FLOWERS AND HORSES]```

A list can have other lists as elements. Type the following example which uses a list of two lists as the second input:

```BM "WILD [[WILD FLOWERS] [WILD HORSES]]
Result: [[WILD FLOWERS] [WILD HORSES]]```

The word `WILD` is not matched with either of the `WILD` words in the second input because the word `WILD` is not an element of the second input - the second input has two elements, both of which are lists. Type:

```BM [WILD HORSES] [[WILD FLOWERS] [WILD HORSES]]
Result: [[WILD FLOWERS]]```

The `FROMMEMBER` command (`FM` for short) takes two inputs. It finds the first occurrence of the first input in the list you give it as the second input and outputs a list with the elements from that point to the end of the second input. The first input can be either a word or a list.Type:

```FM "FLOWERS [WILD FLOWERS HORSES MUSHROOMS]
Result: [FLOWERS HORSES MUSHROOMS]```

Sometimes, getting an element of a list at random is useful. Suppose you want to make random noise. You could define a list of `PLAY` commands and then randomly select one to play. Type:

`MAKE "NOISE [[PLAY "CARHORN] [PLAY "WASP] [PLAY "TOILETFLUSH]]`

When you want the noise to play, just type:

`RUN PICK :NOISE`

Putting Lists Together

Just so you can see that putting a list together does not change anything, enter the following commands to create two variables:

```MAKE "PART1 [WILD]
MAKE "PART2 [FLOWERS]```

The `LIST` command normally takes two inputs and combines them to form a new list. Type:

```LIST :PART1 :PART2
Result: [[WILD] [FLOWERS]]```

The output of `LIST` is a new list made from the two parts. The parts are not affected. Type:

```(SHOW :PART1 :PART2)
[WILD] [FLOWERS]```

None of the commands that put lists together actually change the input parts. The output of these commands is made up from copies of the inputs. If you want the value of a variable changed, you have to use `MAKE`. For example, type:

```MAKE "PART1 LIST :PART1 :PART2
SHOW :PART1
[[WILD] [FLOWERS]]```

Now, `PART1` has a new value. The rest of the examples will use the actual inputs rather than variables - it's easier to follow what's going on that way.

The `LIST` command maintains the structure of its inputs in the list that it creates. In the example above, both of the inputs were lists, so the output was a list of two lists. `LIST` can use words as inputs, too. Type:

```LIST "WILD "FLOWERS
Result: [WILD FLOWERS]```

The input words are still words within the output list. This type of list is called a sentence in Logo. The `SENTENCE` command (`SE` for short) outputs a list, too. However, it does not maintain the structure of its inputs like `LIST` does. The output of `LIST` and `SENTENCE` are the same sometimes, but not always. Type:

```SE "WILD "FLOWERS
Result: [WILD FLOWERS]```

With two words as input, the output of `SENTENCE` is the same as `LIST`. However, type:

```SE [WILD] [FLOWERS]
Result: [WILD FLOWERS]

LIST [WILD] [FLOWERS]
Result: [[WILD] [FLOWERS]]```

This is an important and significant difference. If you need a list with just words, then use `SENTENCE` to create the list and to modify it. If you need to maintain the structure of the elements of a list, then use `LIST` to create the list and to modify it. Mixing the use of `SENTENCE` and `LIST` can lead to problems. If you accidentally give `SENTENCE` a list with other lists as elements, the result will not be a sentence, as you might have expected. Type:

```SE [WILD FLOWERS] [[WILD HORSES] [WILD MUSHROOMS]]
Result: [WILD FLOWERS [WILD HORSES] [WILD MUSHROOMS]]```

The output of `SENTENCE` in this case is not a sentence because there are lists as elements. Be careful.

A new list can be put together with more than two parts by enclosing the command and its inputs within parentheses. Type:

```(LIST "BIG "DOGS "DIG "DEEP "HOLES)
Result: [BIG DOGS DIG DEEP HOLES]

(SE "BIG "DOGS "DIG "DEEP "HOLES)
Result: [BIG DOGS DIG DEEP HOLES]```

Since all of the inputs were words, the output of both `LIST` and `SENTENCE` are the same. You can also create a new one-element list. Type:

```(LIST "ONE)
Result: [ONE]

(SE "ONE)
Result: [ONE]```

The `FPUT` command outputs a new list by putting its first input in front of its second input. In other words, the first input is put first in the new list. Furthermore, `FPUT` maintains the structure of its first input within the new list so that the `FIRST` of the new list is the same as the first input to `FPUT`. Type:

```FPUT "WILD [FLOWERS]
Result: [WILD FLOWERS]

FIRST FPUT "WILD [FLOWERS]
Result: WILD```

If the first input to `FPUT` is a list, the structure of it is still maintained in the output. Type:

```FPUT [WILD FLOWERS] [[WILD HORSES] [WILD MUSHROOMS]]
Result: [[WILD FLOWERS] [WILD HORSES] [WILD MUSHROOMS]]

FIRST FPUT [WILD FLOWERS] [[WILD HORSES] [WILD MUSHROOMS]]
Result: [WILD FLOWERS]```

The opposite of `FPUT` is the `LPUT` command. `LPUT` outputs a new list by putting its first input at the end of its second input. In other words, the first input is put last in the new list. Furthermore, `FPUT` maintains the structure of its first input within the new list so that the `LAST` of the new list is the same as the first input to `LPUT`. Type:

```LPUT "FLOWERS [WILD]
Result: [WILD FLOWERS]

LAST LPUT "FLOWERS [WILD]
Result: FLOWERS```

If the first input to `LPUT` is a list, the structure of it is still maintained in the output. Type:

```LPUT [WILD MUSHROOMS] [[WILD FLOWERS] [WILD HORSES]]
Result: [[WILD FLOWERS] [WILD HORSES] [WILD MUSHROOMS]]

LAST LPUT [WILD MUSHROOMS] [[WILD FLOWERS] [WILD HORSES]]
Result: [WILD MUSHROOMS]```

You can change all occurrences of one word in a list with the `SUBST` command. It replaces all occurrences of its first input with its second input wherever the first input appears in the list you give it as the third input. Type:

```SUBST "WILD "TAME [WILD HORSES]
Result: [TAME HORSES]```

The substitution is done recursively, which means that it takes place in the lists within a list, too. Type:

```SUBST "WILD "TAME [[WILD FLOWERS] [WILD HORSES]]
Result: [[TAME FLOWERS] [TAME HORSES]]```

Creating new lists from parts can be fun.

```MAKE "MESSAGE [BIG DOGS DIG DEEP HOLES]
MAKE "SECRET []
FOREACH :MESSAGE [MAKE "SECRET LPUT PIG.LATIN "? :SECRET]
PRINT :SECRET
IG-BAY OGS-DAY IG-DAY EEP-DAY OLES-HAY```

`SECRET` begins as the empty list. As `FOREACH` converts the words in `MESSAGE`, the new words are added to the end of `SECRET` with `LPUT`. Do you think `FPUT` would work? Try it and see. What about `SENTENCE`? Another way to make random noise is to have a list of quoted words and then build the instruction to give to the `RUN` command. Type:

```MAKE "NOISE ["CARHORN "WASP "TOILETFLUSH]
RUN LIST "PLAY PICK :NOISE```

Comparing Lists

When you compare two things, you are asking a question. The Logo commands for doing comparisons have a question mark at the end of their names. For example, `LIST?` is a command that asks if its input is a list. The answer (or output) to the question is either the word TRUE or the word FALSE. One way to use `LIST?` is in the `TEST` command. Type:

`TEST LIST? [TERRAPIN LOGO]`

If you want to run some commands when the result of the test is true, you can use the `IFTRUE` command and give it a list of instructions to run. Type:

```IFTRUE [PRINT [YES, THAT'S A LIST]]
YES, THAT'S A LIST```

`IFTRUE` checks the value of `@COND` and if it's TRUE, the instructions in the list are run. The value of `@COND` is not changed until another `TEST` is done. You can put as many `IFTRUE` commands as you want after the `TEST` command. The opposite of `IFTRUE` is `IFFALSE`. Since the current value of `@COND` is TRUE, an `IFFALSE` command at this point would not mean anything. Type:

```TEST LIST? "FLOWER
IFTRUE [PRINT "SMELL]
IFFALSE [PRINT [ALL'S WELL]]
ALL'S WELL```

The `IFTRUE` command does not run its instructions in this example. `IFFALSE` checks the value of `@COND` and if it's `FALSE`, the instructions in the list are run.

An alternative to `TEST` is `IF`. In one form, `IF` is a combination of `TEST`, `IFTRUE` and `IFFALSE`.

```IF LIST? "FLOWER [PRINT "SMELL] [PRINT [ALL'S WELL]]
ALL'S WELL```

The first input to this form of `IF` is the same as the input to `TEST` - a condition that returns either the word TRUE or the word FALSE. The `IF` command does not make use of the `@COND` variable; it uses the result of the test to determine what to do next. The second input is the list of instructions to run when the condition is true. The third input is optional, but if you use it, the instructions in the list are run when the condition is false. Another form of `IF` is similar but does not have lists of instructions. Instead, it uses the special words `THEN` and

`ELSE as markers. When the test condition is true, the `

instructions after `THEN` and up to `ELSE` are run. `ELSE` is optional, so the instructions for `THEN` end at the end of the line if `ELSE` is not used. When the test condition is false, the instructions after `ELSE` and up to the end of the line are run. It's more like the way people say things when they make a decision. The following `IF` command is really the same as the example above:

```IF LIST? "FLOWER THEN PRINT "SMELL ELSE PRINT [ALL'S WELL]
ALL'S WELL```

The form of comparison you use is a matter of personal choice - one way works just as well as another. For more information, look in the online help and the Reference Manual.

The empty list has nothing in it, but it's still a list. You test for the empty list with the `EMPTY?` command. It outputs TRUE if the list is empty and FALSE if it's not empty. If you remove all the elements of a list, you'll end up with the empty list. In the following example, use the up-arrow key and insert additional `BUTFIRST` commands after you try each line. Type:

```EMPTY? BUTFIRST [FLOWERS HORSES MUSHROOMS]
Result: FALSE

EMPTY? BUTFIRST BUTFIRST [FLOWERS HORSES MUSHROOMS]
Result: FALSE

EMPTY? BUTFIRST BUTFIRST BUTFIRST [FLOWERS HORSES MUSHROOMS]
Result: TRUE```

Testing for the empty list is necessary when you want to use all of the elements in a list, one at a time. You know you're done when you find the empty list. The `PRINT.DOWN` procedure takes a list as input and prints it, one element at a time. It checks for the empty list in order to know when to stop printing. After the first element is printed, `PRINT.DOWN` is run with a slightly shorter list - the `BUTFIRST` of the original input list. `PRINT.DOWN` was defined earlier for words, but it works just as well for lists. Type:

```PRINT.DOWN [[WILD FLOWERS] [WILD HORSES]]
WILD FLOWERS
WILD HORSES```

Just like many Logo commands, you'll find that many of your own procedures work equally well with either words or lists.

The `MEMBER?` command takes two inputs and tests to see if the first input is a member of the second input. If a match is found, `MEMBER?` outputs TRUE, otherwise, `MEMBER?` outputs FALSE. The first input can be either a word or a list. Type:

```MEMBER? [WILD HORSES] [[WILD FLOWERS] [WILD HORSES]]
Result: TRUE

MEMBER? "WILD [[WILD FLOWERS] [WILD HORSES]]
Result: FALSE```

The word `WILD` is not an element of the input list - it's a member of a member of the input list. Checking the elements of a list within another list can be done recursively - it's just a bit more complicated than the recursion done by `PRINT.DOWN`. You not only have to test each element of the input list, you also have to check each element of the lists that are elements themselves. And, since a list can have a list as a member, the nesting can get quite deep. The `ANY.MEMBER?` procedure has more than one recursive call in it. In addition, it's purpose is to output either the word TRUE or FALSE, depending on whether or not the first input is a member of any member of the second input. Define `ANY.MEMBER?` and then work through the following examples.

```ANY.MEMBER? "WILD [SOME WILD FLOWERS ARE WEEDS]
Result: TRUE```

With a sentence as the second input, `ANY.MEMBER?` works much like the built-in `MEMBER?` command. It checks to see if the first input is equal to the `FIRST` element of the second input. If they are equal, then it outputs the word TRUE with the `OUTPUT` command, which stops the procedure. If they are not equal, then `ANY.MEMBER?` checks to see if the first element of the second input is another list. If not, then it just outputs the result of running `ANY.MEMBER?` with the `BUTFIRST` of the second input.

```ANY.MEMBER? "WILD [[TAME HORSES] [WILD FLOWERS]]
Result: TRUE```

If the `FIRST` element of the second input is another list, then `ANY.MEMBER?` is run with that list as the second input. However, the result of running `ANY.MEMBER?` can not be output immediately because, if the result was FALSE, the `OUTPUT` command would stop the procedure before it had the chance to check the elements of the `BUTFIRST` of the second input.

```ANY.MEMBER? [WILD] [[WHAT [ABOUT [THIS [WILD]]]]]
Result: TRUE```

`ANY.MEMBER?` works with either a word or a list as the first input, just like the built-in `MEMBER?` command. It just does a little more work when the second input has lists as elements. Have you noticed that the usual form of a Logo instruction is the command word followed by its inputs, if it needs any? This form is called prefix notation - the command word comes first. You can do every Logo command this way and it's easy to remember the format. Some command words look more natural if they go in between their inputs. This is called infix notation and the command words are called operators - in fact, most operators are really symbols, like =. Logo has both commands and operators for the list comparisons: equal and not equal. You can not compare lists to see if one is greater than or less than the other.

All of the comparison operators (represented by symbols) can be used in either a prefix or infix notation. The commands (represented by words) can only be used in a prefix notation. You can often avoid using parentheses to make Logo understand what you are doing if you use prefix notation instead of infix notation. Some examples will show you where parentheses are needed. It's not a big problem, as long as you're aware of it.

To see if two lists are equal to each other, you can use either of the commands `=` or `.EQ` or the operator =. Each of the following commands work the same:

```EQUAL? [WILD FLOWERS] [WILD FLOWERS]
Result: TRUE

.EQ [WILD FLOWERS] [WILD FLOWERS]
Result: TRUE

= [WILD FLOWERS] [WILD FLOWERS]
Result: TRUE

[WILD FLOWERS] = [WILD FLOWERS]
Result: TRUE```

You may need parentheses for the infix notation when the first (or left) input is more complicated than a simple list. It's often a very subtle problem.

```EQUAL? BUTFIRST [WILD FLOWERS] [FLOWERS]
Result: TRUE

BUTFIRST [WILD FLOWERS] = [FLOWERS]
Result: ALSE```

Result `ALSE`? What is that? The = operator has used the list `[WILD FLOWERS]` as its first (left) input and compared it to `[FLOWERS]`. Since they were not equal, it output FALSE which was then input to `BUTFIRST` which output all but the first character of FALSE which is where `ALSE` came from. In cases like this, you need to put parentheses around the first input to an infix operator or change the test to have the simple part as the first input.

```(BUTFIRST [WILD FLOWERS]) = [FLOWERS]
Result: TRUE

[FLOWERS] = BUTFIRST [WILD FLOWERS]
Result: TRUE```

You can reverse the meaning of a test with the `NOT` command. For the prefix notation, just put the `NOT` command in front of the comparison command word or symbol. If you used the infix notation, you can put `NOT` in front of the first (left) input. However, you don't really need to use `NOT` because Logo has all the comparisons you need. It's probably easier and clearer to change the command or operator.

You can read about the rest of the comparison commands and operators in the online help or the Reference Manual. They are an important part of programming. Combined with the `TEST` and `IF` commands, they add a sense of intelligence to your procedures.

Computing with Numbers

The numbers normally used by Logo are represented in the decimal number system, or base 10, which uses the digits 0 through 9. Fortunately, it's the same number system that people use all the time. You should know, however, that Logo can recognize numbers in other bases as well. For example, the prefix `#B` can be used to enter a binary number like `#B1111`, which is equivalent to the decimal number 15.

Logo displays normal decimal numbers unless you change the system variable \$var[variables|BASE] to change the default display. Any base from 2 through 16 can be selected. If you need to use different bases, you can find out more in the online help or the Reference Manual. However, if you play around with \$var[variables|BASE], be aware that regardless of what base you select, displaying the value of \$var[variables|BASE] will always show 10. The right-most position of any number in any base is the one's position. The next position to the left is the ten's position for decimal numbers, but it's the two's position for binary, the eight's position for octal, and the sixteen's position for hexadecimal. It seems like a kind of computer math joke - when is 10 not equal to 10? When you use a different \$var[variables|BASE] for each number. By default, Logo displays fractional numbers rounded to the nearest hundredths position - or, at most, two decimal places. You can change the system variable \$var[variables|PRECISION] to control how many decimal places you want to see. All internal values have a precision of 15 decimal places regardless of the setting of \$var[variables|PRECISION]. If you only want whole numbers to display, you can set \$var[variables|PRECISION] to 0. The maximum setting is 15.

The leading zero of a number is not relevant to its value. For example, the numbers 0123 and 123 are equal to the value of one hundred twenty three. However, if you put a double quotation mark in front of a number with leading zeros, then the zeros will remain for display purposes only - it will not affect the value.

Numbers are every bit as important as words and lists. Knowing more about numbers can make your Logo experience more fun. You can count on it!

Taking Numbers Apart

Since numbers are also valid Logo words, all of the commands that work for words also work for numbers. The elements of a number are the individual characters that make up the number. The elements are usually the digits 0 through 9, but the decimal point and minus sign may also be elements of numbers.

The following examples show how numbers can be taken apart with the same commands that were used for words. The result is typically still a number. However, if you remove all of the elements of a number, you will end up with the empty word. The empty word is not a number.

```FIRST 123
Result: 1
LAST 123
Result: 3
BUTFIRST 123
Result: 23
BUTLAST 123
Result: 12
BUTMEMBER 0 2000
Result: 2
FROMMEMBER 4 123456789
Result: 456789
PICK 123456
Result: 3
ITEM 3 123456
Result: 3
ITEM COUNT 1234 1234
Result: 4```

The individual numeric digits also have an ASCII value, just like the other characters. Type:

```CHAR 49
Result: 1```

Thinking of numbers as words is a little different than thinking of them as numeric values all the time. Most of your work with numbers will likely be in calculations, but sometimes these manipulations can be handy, too. Suppose you wanted to test whether a 3-sided die is statistically equivalent to a 6-sided die that has duplicates of the three different numbers. A 3-sided die could be simulated with the number word 123 while the 6-sided die could be simulated with the number word 112233. You could use `PICK 123` and `PICK 112233` to simulate rolling the dice. Do you think `RANDOM 3` is statistically equivalent? What if you want to use an “unfair” die - where one number appears more than the others? For example, ```PICK 172737475767``` is more likely to roll a 7 than any of the other numbers. This would be more difficult to simulate with `RANDOM`.

Putting Numbers Together

Numbers can be put together with the same commands that work for words. The result is typically still a number. However, if you put two decimal numbers together, you will not have a number as a result.

```WORD 12 34
Result: 1234
FPUT 1 234
Result: 1234
LPUT 4 123
Result: 1234
SUBST 1 2 1234
Result: 2234```

Why would you want to manipulate numbers like words? Sometimes it's convenient to use a number as part of the name for a variable or an object, like a graphical control. For example, `SCORE.1` and `SCORE.2` could be the names of the statictext controls for displaying the total scores of players in a game. The variable `CURRENT.PLAYER` could represent the number 1 or 2, depending on whose turn it is. When you need to update the current player's score, you could use `WORD “SCORE. :CURRENT.PLAYER` to create the proper name of the control.

Comparing Numbers

All numbers are words, but not all words are numbers. If you need to check whether or not a word is a number, use the `NUMBER?` command. It outputs only if its input word can be interpreted as a numeric value; otherwise, it outputs . One way to use `NUMBER?` is in the `TEST` command. Type:

`TEST NUMBER? 123`

`TEST` is a rather special command. It doesn't output anything, but it does “remember” the result of the test in a variable called `@COND`. If you want to run some commands when the result of the test is true, you can use the `IFTRUE` command and give it a list of instructions to run. Type:

```IFTRUE [PRINT [YES, THAT'S A NUMBER]]
YES, THAT'S A NUMBER```

`IFTRUE` checks the value of `@COND` and if it's TRUE, the instructions in the list are run. The value of `@COND` is not changed until another `TEST` is done. You can put as many `IFTRUE` commands as you want after the `TEST` command. The opposite of `IFTRUE` is `IFFALSE`. Since the current value of `@COND` is TRUE, an `IFFALSE` command at this point would not mean anything. Type:

```TEST NUMBER? "SEVEN
IFTRUE [PRINT "THANKS]

The `IFTRUE` command does not run its instructions in this example. `IFFALSE` checks the value of `@COND` and if it's FALSE, the instructions in the list are run.

An alternative to `TEST` is `IF`. In one form, `IF` is a combination of `TEST`, `IFTRUE` and `IFFALSE`.

```IF NUMBER? "SEVEN [PRINT "THANKS] [PRINT [NUMBER, PLEASE.]]

The first input to this form of `IF` is the same as the input to `TEST` - a condition that returns either the word TRUE or the word FALSE. The `IF` command does not make use of the `@COND` variable; it uses the result of the test to determine what to do next. The second input is the list of instructions to run when the condition is true. The third input is optional, but if you use it, the instructions in the list are run when the condition is false. Another form of `IF` is similar but does not have lists of instructions. Instead, it uses the special words `THEN` and `ELSE` as markers. When the test condition is true, the instructions after `THEN` and up to `ELSE` are run. `ELSE` is optional, so the instructions for `THEN` end at the end of the line if `ELSE` is not used. When the test condition is false, the instructions after `ELSE` and up to the end of the line are run. It's more like the way people say things when they make a decision. The following `IF` command is really the same as the example above:

```IF NUMBER? "SEVEN THEN PR "THANKS ELSE PR [NUMBER, PLEASE.]

The form of comparison you use is a matter of personal choice - one way works just as well as another. For more information, look in the online help and the Reference Manual.

The empty word has nothing in it - it's still a word but it is not a number. You test for the empty word with the `EMPTY?` command. It outputs TRUE if the word is empty and FALSE if it's not empty. If you remove all the characters of a number, you'll end up with the empty word. In the following example, use the up-arrow key and insert additional `BUTFIRST` commands after you try each line. Type:

```EMPTY? BUTFIRST "123
Result: FALSE
EMPTY? BUTFIRST BUTFIRST "123
Result: FALSE
EMPTY? BUTFIRST BUTFIRST BUTFIRST "123
Result: TRUE
NUMBER? EMPTY? BUTFIRST BUTFIRST BUTFIRST "123
Result: FALSE```

Testing for the empty word is necessary when you want to use all of the characters in a number, one at a time. You know you're done when you find the empty word. The `PRINT.DOWN` procedure from earlier works for words and lists; since a number is also a word, it works for numbers, too. Type:

```PRINT.DOWN 54321
5
4
3
2
1```

Sometimes you need to know whether or not a number is odd or even. Of course, there are ways to determine that with a calculation, but it's not necessary. Odd numbers end with one of the digits 1, 3, 5, 7, or 9. The `MEMBER?` command takes two inputs and tests to see if the first input is a member of the second input. If a match is found, `MEMBER?` outputs TRUE, otherwise, `MEMBER?` outputs FALSE. Type:

```MEMBER? LAST 123 "13579
Result: TRUE
MEMBER? LAST 456 "02468
Result: TRUE```

You could define procedures called `ODD?` and `EVEN?` to test for odd and even numbers.

The `PIG.LATIN` procedure you defined earlier should just output numbers with no change. Add the following test at the beginning of `PIG.LATIN`.

`IF NUMBER? :INPUT THEN OUTPUT :INPUT`

There are even more rules to Pig Latin - odd, isn't it? Have you noticed that the usual form of a Logo instruction is the command word followed by its inputs, if it needs any? This form is called prefix notation - the command word comes first. You can do every Logo command this way and it's easy to remember the format. Some command words look more natural if they go in between their inputs. This is called infix notation and the command words are called operators - in fact, most operators are really symbols, like =, <, and >. Logo has both commands and operators for the comparisons: equal, greater than, greater than or equal, less than, less than or equal, and not equal.

All of the comparison operators (represented by symbols) can be used in either a prefix or infix notation. The commands (represented by words) can only be used in a prefix notation. You can often avoid using parentheses to make Logo understand what you are doing if you use prefix notation instead of infix notation. Some examples will show you where parentheses are needed. It's not a big problem, as long as you're aware of it.

To see if two numbers are of equal value, you can use either of the commands `=` or `.EQ` or the operator =. Each of the following commands work the same:

```EQUAL? 123 123
Result: TRUE
.EQ 123 123
Result: TRUE
= 123 123
Result: TRUE
123 = 123
Result: TRUE```

You may need parentheses for the infix notation when the first (or left) input is more complicated than a simple number. It's often a very subtle problem.

```EQUAL? FIRST 123 1
Result: TRUE
FIRST 123 = 1
Result: F```

Result F? What is that? The = operator has used the number 123 as its first (left) input and compared it to 1. Since they were not equal, it output FALSE which was then input to `FIRST` which output the first character of FALSE which is where the F came from. In cases like this, you need to put parentheses around the first input to an infix operator or change the test to have the simple word as the first input.

```(FIRST 123) = 1
Result: TRUE
1 = FIRST 123
Result: TRUE```

You can reverse the meaning of a test with the `NOT` command. For the prefix notation, just put the `NOT` command in front of the comparison command word or symbol. If you used the infix notation, you can put `NOT` in front of the first (left) input. However, you don't really need to use `NOT` because Logo has all the comparisons you need. It's probably easier and clearer to change the command or operator.

You can read about the rest of the comparison commands and operators in the online help or the Reference Manual. They are an important part of programming. Combined with the `TEST` and `IF` commands, they add a sense of intelligence to your procedures.

Logo Math

Of course, Logo can do math - add, subtract, multiply, divide, and many other mathematical operations as well. People normally do math with infix notation. For example, type:

```1 + 2
Result: 3```

The + symbol is used for addition. When used in infix notation like this, it takes two inputs - one on the left and one on the right. All of the mathematical operators can be used in prefix notation as well. Type:

```+ 1 2
Result: 3```

And, each of the mathematical operators has a corresponding command word that only works in prefix notation. Type:

```SUM 1 2
Result: 3```

The prefix notation form of mathematical operators normally take two inputs. However, if you enclose the command or operator and its inputs with parentheses, then any number of inputs can be used. Type:

```(+ 1 2 3 4 5)
Result: 15

(SUM 1 2 3 4 5)
Result: 15```

The form of notation you use is your own choice. Sometimes the prefix notation is easier to work with. It may take a little getting used to, but it does have some advantages, especially when more than one operation is in an instruction line. For example, type:

```1 + 2 * 3 + 4
Result: 11```

The infix operators have an order of precedence that determines which operations are done before others. In this example, since multiplication has a higher precedence than addition, the multiplication of 2 * 3 was done first, giving a value of 6; then, the addition was done (1 + 6 + 4) which resulted in a value of 11. You can control the order of precedence with parentheses. Type:

```(1 + 2) * (3 + 4)
Result: 21```

Using the prefix commands, you can avoid the need for parentheses. Type:

```PRODUCT SUM 1 2 SUM 3 4
Result: 21```

If you cause an error message with a math instruction, Logo always uses the command word rather than the symbol in the text of the error message. Type:

```"TWO / "ONE
QUOTIENT needs a number```

You do have to type a little more with the prefix commands - subtraction is done with the `-` command. However, you can always create an `ALIAS`. Type:

```ALIAS "SUM "ADD
ALIAS "SUM "PLUS
ALIAS "DIFFERENCE "SUB
ALIAS "DIFFERENCE "MINUS
ALIAS "PRODUCT "MUL
ALIAS "PRODUCT "TIMES
ALIAS "QUOTIENT "DIV
ALIAS "QUOTIENT "GOZINTA```

Loopy Math

If you repeatedly add 1 to a variable, you would expect the value to grow larger and larger. That's a normal expectation, but sometimes it's necessary to control the range of a variable so that it is always within a particular range of values. There are many ways to do this, but using the `REMAINDER` command may be the simplest, once you understand what is going on with it. Type:

```MAKE "STEP 4
REMAINDER :STEP 4
Result: 0```

The `REMAINDER` command divides its first input by its second input and outputs the remainder of the division. In this example, the remainder is 0 because 4 goes into 4 just 1 time and there is no remainder. If you repeatedly add 1 to `:STEP`, it will get larger and larger, but the output of `REMAINDER` will not get beyond 3. Type:

```REPEAT 5 [MAKE "STEP :STEP + 1 (PRINT :STEP REMAINDER :STEP 4]
5 1
6 2
7 3
8 0
9 1```

The value of `:STEP` is getting larger but the output of `REMAINDER` stays in the range from 0 to 3. This kind of controlled sequence can be quite useful for “loopy” things that need to stay within a range from 0 to one less than the number of things. Of course, people would rather see a range starting from 1 to a maximum number. There is rather simple formula you can use that will keep a variable within a range from 1 to a maximum value. There are some initializations you need to make before you use the formula - assign the maximum value to the variable you want to use for looping and to another variable that you must never change (in other words, a constant data item). Type:

```MAKE "MAX.STEP 4
MAKE "STEP :MAX.STEP ```

`:STEP` is going to be used in doing loopy things. There is no such thing as a constant (unchangeable) data item in Logo, but the intent of `:MAX.STEP` is that whenever you need the maximum number of steps, you can always get it from `:MAX.STEP`. You'll see why `:STEP` is initialized to the maximum number of steps very shortly. Each time you need to use `:STEP`, you must first assign it a new value with the following command:

`MAKE "STEP 1 + REMAINDER :STEP :MAX.STEP`

The first time a new value is assigned to `:STEP`, the value will be 1 because the `REMAINDER` command will output 0. The next time a new value is assigned, it will be 2 because the `REMAINDER` command will output 1 - at this point, `:STEP` is 1, `:MAX.STEP` is always 4, and the remainder of dividing 1 by 4 is 1. Repeatedly running the `MAKE` command will make **STEP reach the maximum value and then “loop” back to 1 automatically. Type:

```REPEAT 5 [MAKE "STEP 1 + REMAINDER :STEP :MAX.STEP PR :STEP]
2
3
4
1
2```

If you create a procedure to do the assignment and output the new value, you can use the procedure name whenever you need the next value of `:STEP`. Define the `NEXT.STEP` procedure. It does not have any inputs - it's expecting to have access to `:STEP` and `:MAX.STEP` as global variables (like what you are using now). Of course, with dynamic scope, they could be defined in a superprocedure as well. Type:

```REPEAT 5 [PRINT NEXT.STEP]
3
4
1
2
3```

What about the sequences that start with 0? All you have to do is change the `OUTPUT` command to subtract 1 from the `:STEP`. Of course, you could subtract 1 from `NEXT.STEP` yourself. Type:

```REPEAT 5 [PRINT NEXT.STEP - 1]
3
0
1
2
3```

But, why not let your procedure do the subtraction for you? You might forget.

Math is really a fundamental part of working with any computer. Fortunately, most of it is rather incidental to doing fun things with turtles, bitmaps and drawings. Logo has a wide range of commands and operators that you can use to explore mathematics - from simple basic math to trigonometry and polar coordinates. If you're interested in mathematics, you can check out Logo's mathematical capabilities in the online help or the Reference Manual.

A Turtle Flight Plan

Turtles move in straight lines, but if you connect enough short lines together, you can make a turtle orbit the earth and do loopty-loops at the same time. All you need to do is file a flight plan before launching your turtle on its flight. (After you have defined the ten procedures in the illustration, of course.)

A flight plan is just a list of coordinate points put on the turtle's property list with the name `FLIGHTPLAN`. There are many different ways to make a flight plan. You can invent your own later on. `MAKEPLAN` takes three inputs: the number of points you want in the plan, the radius of the circle that encloses the flight path, and the direction in which the turtle should fly - either the word `RIGHT` or `LEFT`. The local variable `:PLAN` is used to create the list of coordinate points for the flight plan. As the new turtle named `PLANNER` is moved to each point, the coordinate point is added to `:PLAN`. A Logo command is just a word until you run it - `PLANNER` turns right or left, depending on the value of `DIRECTION`. When the plan is complete, `PLANNER` is erased and the flight plan is output. Type:

```MAKEPLAN 4 100 "RIGHT
Result: [[0 100] [100 0] [0 -100] [-100 0]]```

With just four points in the plan, the turtle would follow the path of a square - not a very likely flight path. However, it shows you what a flight plan looks like.

Filing a flight plan is just a matter of putting the plan on the turtle's property list. As you learned in Chapter 6 - Property Lists, it's best to create a procedure to manipulate the property list. The`FILEPLAN` procedure takes a turtle number and a flight plan as input. The flight plan is filed as the value of the property name `FLIGHTPLAN`.

To file a flight plan for turtle 0, type:

`FILEPLAN 0 MAKEPLAN 4 100 "RIGHT`

To launch your turtle on its flight, just use `FLIGHT`. It takes the turtle number as input and gets the turtle moving. Type:

`PENUP FLIGHT 0`

The reason for doing `PENUP` first is that the turtle is not likely to be at the point of takeoff when you put it in flight. If you want to see a trail of the flight path, put the pen back down while the turtle is flying. The `FLIGHT` procedure uses `LAUNCH` to start the `TAKEOFF` procedure. The process identification number output by `LAUNCH` is saved on the turtle's property list so the `LAND` procedure can use it later when you want to stop the turtle.

The `TAKEOFF` procedure creates three local variables which are accessible by the other subprocedures that it runs. `:PLAN` is a copy of the turtle's flight plan. In a real flight plan, there are checkpoints along the route. `:MAXPOINTS` is initialized with the output of `CHECKPOINTS`, which counts the coordinate points in the flight plan. `:POINT` is used as a counter as the turtle moves from one point to the next.

The `PRFLIGHT` procedure just moves the turtle to the first coordinate point in the flight plan. Flying a turtle is just moving from one point to the next - just the type of thing that loopy math was made for. The `FLY` procedure does the loopy math with `:POINT` and `:MAXPOINTS` and then calls on `NEXTPOINT` to actually move the turtle to the next checkpoint. `NEXTPOINT` turns the turtle towards the checkpoint and takes one step at a time until the turtle arrives at the checkpoint coordinate (hopefully on time). The turtle continues to fly forever, until you request it to land. The `LAND` procedure uses the process identification number from the turtle's property list and uses it as input to the `HALT` command to stop the turtle.

To see a flight plan that has been filed, use `GETPLAN`. It takes the turtle number as input and outputs the flight plan. Type:

```GETPLAN 0
Result: [[0 100] [100 0] [0 -100] [-100 0]]```

What about the loopty-loops?. All you need is a different flight plan. The `CAPTURE` procedure is one example of making a flight plan by using the mouse. Once you start `CAPTURE`, you have two seconds to put the mouse pointer where you want to start. Hold the button down as you draw your flight plan. As long as the button is down, new (and different) coordinates are saved in `:PLAN`. When you release the button, `CAPTURE` outputs the flight plan. You can make some very complicated flight plans with `CAPTURE`. Not only loopty-loops, but you could write your name and use that as the flight plan. You'll have to be creative to dot your I's and cross your T's.

If you want a flight plan that just goes from “point A to point B” rather than looping repeatedly, you'll have to change the `FLY` procedure. You could use a `FOR` command to call the `NEXTPOINT` procedure for each coordinate and then stop. You can make the turtle move faster by changing the `NEXTPOINT` procedure. Try using either `SETXY` or `FORWARD` `DISTANCE` `CHECKPOINT`. This will make the turtle move much faster but not as smoothly.

To make a more realistic orbital flight path, try the `MAKE.ORBIT` procedure. It takes three inputs: the number of points you want in the flight plan, the horizontal and the vertical radius of the ellipse that outlines the flight path. The turtle stamps an ellipse with `STAMPOVAL` and then calls on `GET.POINT` which makes the turtle “walk” outward until it finds the line.

A circle drawn on a computer screen is really an illusion. The `POLY.FLIGHT` procedure creates five different flight plans, starting with a straight line of two points. As more and more points are added to the plans, the flight path gets closer and closer to a circle. Exactly how many sides does a circle have anyway? It depends on your resolution.

```TO POLY.FLIGHT
FILEPLAN 0 MAKEPLAN 2 100 "RIGHT
FILEPLAN 1 MAKEPLAN 4 100 "LEFT
FILEPLAN 2 MAKEPLAN 6 100 "RIGHT
FILEPLAN 3 MAKEPLAN 8 100 "LEFT
FILEPLAN 4 MAKEPLAN 10 100 "RIGHT
TELL [0 1 2 3 4]
EACH [SHOWTURTLE PENUP FLIGHT WHO]
END```