diff options
author | elioat <elioat@tilde.institute> | 2023-08-23 07:52:19 -0400 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2023-08-23 07:52:19 -0400 |
commit | 562a9a52d599d9a05f871404050968a5fd282640 (patch) | |
tree | 7d3305c1252c043bfe246ccc7deff0056aa6b5ab /js/games/nluqo.github.io/~bh/v1ch3 | |
parent | 5d012c6c011a9dedf7d0a098e456206244eb5a0f (diff) | |
download | tour-562a9a52d599d9a05f871404050968a5fd282640.tar.gz |
*
Diffstat (limited to 'js/games/nluqo.github.io/~bh/v1ch3')
-rw-r--r-- | js/games/nluqo.github.io/~bh/v1ch3/mercedes.gif | bin | 0 -> 1080 bytes | |||
-rw-r--r-- | js/games/nluqo.github.io/~bh/v1ch3/taxiframe.gif | bin | 0 -> 1037 bytes | |||
-rw-r--r-- | js/games/nluqo.github.io/~bh/v1ch3/v1ch3.html | 1083 | ||||
-rw-r--r-- | js/games/nluqo.github.io/~bh/v1ch3/variab.html | 1083 |
4 files changed, 2166 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/v1ch3/mercedes.gif b/js/games/nluqo.github.io/~bh/v1ch3/mercedes.gif new file mode 100644 index 0000000..517292c --- /dev/null +++ b/js/games/nluqo.github.io/~bh/v1ch3/mercedes.gif Binary files differdiff --git a/js/games/nluqo.github.io/~bh/v1ch3/taxiframe.gif b/js/games/nluqo.github.io/~bh/v1ch3/taxiframe.gif new file mode 100644 index 0000000..00408d9 --- /dev/null +++ b/js/games/nluqo.github.io/~bh/v1ch3/taxiframe.gif Binary files differdiff --git a/js/games/nluqo.github.io/~bh/v1ch3/v1ch3.html b/js/games/nluqo.github.io/~bh/v1ch3/v1ch3.html new file mode 100644 index 0000000..178b7fe --- /dev/null +++ b/js/games/nluqo.github.io/~bh/v1ch3/v1ch3.html @@ -0,0 +1,1083 @@ +<HTML> +<HEAD> +<TITLE>Computer Science Logo Style vol 1 ch 3: Variables</TITLE> +</HEAD> +<BODY> +<CITE>Computer Science Logo Style</CITE> volume 1: +<CITE>Symbolic Computing</CITE> 2/e Copyright (C) 1997 MIT +<H1>Variables</H1> + +<TABLE width="100%"><TR><TD> +<IMG SRC="../csls1.jpg" ALT="cover photo"> +<TD><TABLE> +<TR><TD align="right"><CITE><A HREF="http://www.cs.berkeley.edu/~bh/">Brian +Harvey</A><BR>University of California, Berkeley</CITE> +<TR><TD align="right"><BR> +<TR><TD align="right"><A HREF="../pdf/v1ch03.pdf">Download PDF version</A> +<TR><TD align="right"><A HREF="../v1-toc2.html">Back to Table of Contents</A> +<TR><TD align="right"><A HREF="https://people.eecs.berkeley.edu/~bh/v1ch2/v1ch2.html"><STRONG>BACK</STRONG></A> +chapter thread <A HREF="../v1ch4/v1ch4.html"><STRONG>NEXT</STRONG></A> +<TR><TD align="right"><A HREF="https://mitpress.mit.edu/books/computer-science-logo-style-second-edition-volume-1">MIT +Press web page for Computer Science Logo Style</A> +</TABLE></TABLE> + +<HR> + +<P> +In the last chapter I suggested that you would find yourself limited +in writing new procedures because your procedures don't take inputs, +so they do exactly the same thing every time you use them. In this +chapter we'll overcome that limitation. + +<P><H2>User Procedures with Inputs</H2> + +<P>As a first example I'm going to write a very simple command named +<CODE>greet</CODE>, which will take a person's name as its one input. Here's how +it will work: + +<P><PRE>? <U>greet "Brian</U> +Hello, Brian +Pleased to meet you. +? <U>greet "Emma</U> +Hello, Emma +Pleased to meet you. +</PRE> + +<P>This procedure will be similar to the <CODE>hello</CODE> command in the +last chapter, except that what it prints will depend on the input +we give it. + +<P> +Each time we <EM>invoke</EM> <CODE>greet</CODE>, we want to give it an input. +So that Logo will expect an input, we must provide for one +when we <EM>define</EM> <CODE>greet</CODE>. (Each procedure has a definite number +of inputs; if <CODE>greet</CODE> takes one input once, it must take one input every +time it's invoked.) Also, in order for the instructions inside <CODE>greet</CODE> +to be able to use the input, we must give the input a <EM>name.</EM> +Both of these needs are met in the <CODE>to</CODE> command that supplies the title +line for the procedure: + +<P><PRE>? <U>to greet :person</U> +</PRE> + +<P>You are already familiar with the use of the <CODE>to</CODE> command, +the need for a word like <CODE>greet</CODE> to name the procedure, and the appearance +of the greater-than prompt instead of the question mark. What's new +here is the use of <CODE>:person</CODE> after the procedure name. This addition +tells Logo that the procedure <CODE>greet</CODE> will require one input and that +the name of the input will be <CODE>person</CODE>. It may help to think of the +input as a container; when the procedure <CODE>greet</CODE> is invoked, something +(such as the word <CODE>Brian</CODE> or the word <CODE>Emma</CODE>) will be put into the +container named <CODE>person</CODE>. + +<P>Why is the colon used in front of the name <CODE>person</CODE>? Remember that +the inputs to <CODE>to</CODE>, unlike the inputs to all other Logo procedures, +are <EM>not</EM> evaluated before <CODE>to</CODE> is invoked. Later we'll see that +a colon has a special meaning to the Logo evaluator, but that special +meaning is <EM>not</EM> in effect in a title line. Instead, the colon +is simply a sort of mnemonic decoration to make a clear distinction +between the word <CODE>greet</CODE>, which is a <EM>procedure</EM> name, and the word +<CODE>person</CODE>, which is an <EM>input</EM> name. Some versions of Logo don't +even require the colon; you can experiment with yours if you're curious. +(By the way, if you want to sound like a Logo maven, you should pronounce +the colon "dots," as in "to greet dots person.") + +<P>To see why having a name for the input is helpful, look at the rest +of the procedure definition: + +<P><PRE>> <U>print sentence "Hello, thing "person</U> +> <U>print [Pleased to meet you.]</U> +> <U>end</U> +? +</PRE> + +<P>You already know about <CODE>print</CODE> and <CODE>sentence</CODE> and about +quoting words with the quotation mark and quoting lists with square +brackets. What's new here is the procedure <CODE>thing</CODE>. + +<P><CODE>Thing</CODE> is an operation. It takes one input, which must be a word +that's the name of a container. The output from <CODE>thing</CODE> +is whatever datum is in the container. + +<P>The technical name for what I've been calling a "container" is a +<EM>variable.</EM> Every variable has a <EM>name</EM> and a <EM>thing</EM> +(or <EM>value</EM>). The name and the thing are both <EM>parts of</EM> the +variable. We'll sometimes speak loosely of "the variable <CODE> +person</CODE>," but you should realize that this <EM>is</EM> speaking +loosely; what we should say is "the variable named <CODE>person</CODE>." +<CODE>Person</CODE> itself is a <EM>word,</EM> which is different from a +variable. + +<P>When I type the instruction + +<P><PRE>greet "Brian +</PRE> + +<P>the Logo interpreter starts with the first word on the line, +<CODE>greet</CODE>. As usual, Logo takes this to be the name of a procedure. +Logo discovers that <CODE>greet</CODE> requires one input, so it continues to the +next thing on the line. This is a quoted word, <CODE>"Brian</CODE>. Since +it's quoted, it requires no further interpretation. The word <CODE>Brian</CODE> +itself becomes the input to <CODE>greet</CODE>.<SUP>*</SUP> + +<P><SMALL><BLOCKQUOTE><SMALL><SUP>*</SUP>While reading the definition +of <CODE>greet</CODE>, it's easy to say "the input is <CODE>person</CODE>"; then, while +reading an invocation of <CODE>greet</CODE>, it's easy to say "the input is <CODE> +Brian</CODE>." To avoid confusion between the input's name and its value, there +are more precise technical terms that we can use when necessary. The name +of the input, given in the title line of the procedure definition, is called +a <EM>formal parameter.</EM> The value of the input, given when the +procedure is invoked, is called an <EM>actual argument.</EM> In +case the actual argument is the result of a more complicated subexpression, +as in the instruction + +<P><PRE>greet first [Brian Harvey] +</PRE> + +<P>we might want to distinguish between the <EM>actual argument +expression,</EM> <CODE>first [Brian Harvey]</CODE>, and the <EM>actual argument +value,</EM> which is the word <CODE>Brian</CODE>.</SMALL></BLOCKQUOTE></SMALL><P>Logo is now ready to invoke <CODE>greet</CODE>. The first step, before +evaluating the instruction lines in <CODE>greet</CODE>, is to create a +variable to hold the input. This variable is given the word <CODE> +person</CODE> as its <EM>name,</EM> and the word <CODE>Brian</CODE> as its <EM> +thing.</EM> (Please notice that I don't have to know the name +of <CODE>greet</CODE>'s input in order to use it. All I have to know is what +<EM>type of thing</EM>--a person's name--<CODE>greet</CODE> expects as its +input. What are the names of the inputs to a primitive like <CODE> +sentence</CODE>? We don't know and we don't need to know.) + +<P>Logo now evaluates the first instruction in <CODE>greet</CODE>. The process +is just like the ones we went through in such detail in Chapter 2. In +the course of this evaluation Logo invokes the procedure <CODE>thing</CODE> +with the word <CODE>person</CODE> as its input. The output from <CODE>thing</CODE> +is the thing in the variable named <CODE>person</CODE>, namely the word <CODE> +Brian</CODE>. That's how the word <CODE>Brian</CODE> becomes one of the inputs to +<CODE>se</CODE>. Here's a plumbing diagram. + +<P><CENTER><IMG SRC="https://people.eecs.berkeley.edu/~bh/v1ch3/varplumb.gif" ALT="figure: varplumb"></CENTER> + +<P><H2>What Kind of Container?</H2> + +<P>One of the favorite activities that Logo experts use to while away +the time when the computer is down is to argue about the best metaphor +to use for variables. A variable is a container, but what kind of +container? + +<P>One popular metaphor is a mailbox. The mailbox has a <EM>name</EM> painted +on it, like "The Smiths." Inside the mailbox is a piece of +mail. The person from the Post Office assigns a <EM>value</EM> to the +box by putting a letter in it. Reading a letter is like invoking +<CODE>thing</CODE> on the mailbox. + +<P>I don't like this metaphor very much, and if I explain why not, it +may help illuminate for you some details about how variables work. +The first problem is that a real mailbox can contain several letters. +A variable can only contain <EM>one</EM> thing or value. (I should say +"one thing at a time," since we'll see that it's possible to replace +the thing in a variable with a different thing.) + +<P>Another problem with the mailbox metaphor is that to read a letter, +you take it out of the mailbox and tear it open. Then it isn't in +the mailbox any more. When you invoke <CODE>thing</CODE> to look at the thing +in a variable, on the other hand, it's still in the variable. You +could use <CODE>thing</CODE> again and get the same answer. + +<P>There are two metaphors that I like. The one I like best won't make +sense for a while, until we talk about scope of variables. +But here is the one I like second best: Sometimes when you take a +bus or a taxi, there is a little frame up in front that looks like +this: + +<P><CENTER><IMG SRC="taxiframe.gif" ALT="figure: taxiframe"></CENTER> + +<P>The phrase "your driver's name is" is like a label for +this frame, and it corresponds to the <EM>name</EM> of a variable. Each +bus driver has a metal or plastic plate that says "John Smith" +or whoever it is. The driver inserts this plate, which corresponds +to the <EM>value</EM> of the variable, into the frame. You can see why +this is a closer metaphor than the mailbox. There is only one plate +in the frame at a time. To find out who's driving the bus, you just +have to look inside the frame; you don't have to remove the plate. + +<P>(To be strictly fair I should tell you that some Logoites +don't like the whole idea of containers. They have a completely different +metaphor, which involves sticking labels on things. But I think it +would only confuse you if I explained that one right now.) + +<P><H2>An Abbreviation</H2> + +<P>Examining the value of a variable is such a common thing to do in +a Logo procedure that there is a special abbreviation for it. Instead +of the expression + +<P><PRE>thing "person +</PRE> + +<P>you can simply say + +<P><PRE>:person +</PRE> + +<P>So in the <CODE>greet</CODE> procedure, we could have said + +<P><PRE>print sentence "hello :person +</PRE> + +<P>Please note that the colon is <EM>not</EM> just an abbreviation +for the word <CODE>thing</CODE> but rather for the combination <CODE>thing</CODE>-quote. + +<P>When drawing plumbing diagrams, treat <CODE>:narf</CODE> as if it were spelled out +as <CODE>thing "narf</CODE>. + +<P><H2>More Procedures</H2> + +<P>It's time to invent more procedures. I'll give you a couple of examples +and you should make up more on your own. + +<P><PRE>to primer :name +print (sentence first :name [is for] word :name ".) +print (sentence "Run, word :name ", "run.) +print (sentence "See :name "run.) +end + +? <U>primer "Paul</U> +P is for Paul. +Run, Paul, run. +See Paul run. +</PRE> + +<P> + +<P><CODE>Primer</CODE> uses the extra-input kludge I mentioned near the +end of Chapter 2. It also shows how the operations <CODE>word</CODE> and +<CODE>sentence</CODE> can be used in combination to punctuate a sentence +properly. + +<P>With all of these examples, incidentally, you should take the time to +work through each instruction line to make sure you understand what +is the input to what. + +<P><PRE>to soap.opera :him :her :it +print (sentence :him "loves word :her ".) +print (sentence "However, :her [doesn't care for] :him "particularly.) +print (sentence :her [is madly in love with] word :it ".) +print (sentence :him [doesn't like] :it [very much.]) +end + +? <U>soap.opera "Bill "Sally "Fred</U> +Bill loves Sally. +However, Sally doesn't care for Bill particularly. +Sally is madly in love with Fred. +Bill doesn't like Fred very much. +</PRE> + +<P> +In this example you see that a procedure can have more than +one input. <CODE>Soap.opera</CODE> has three inputs. You can also see why each +input must have a name, so that the instructions inside the procedure +have a way to refer to the particular input you want to use. You +should also notice that <CODE>soap.opera</CODE> has a period in the middle of its +name, not a space, because the name of a procedure must be a single +Logo word. + +<P> + +<P> +For the next example I'll show how you can write an <EM>interactive</EM> +procedure, which reads something you type on the keyboard. For this +we need a new tool. <CODE>Readlist</CODE> is an operation with no inputs. Its +output is always a list, containing whatever you type on a single +line (up to a RETURN). <CODE>Readlist</CODE> waits for you to type a line, then +outputs what you type. + +<P><PRE>to converse +print [Please type your full name.] +halves readlist +end + +to halves :name +print sentence [Your first name is] first :name +print sentence [Your last name is] last :name +end + +? <U>converse</U> +please type your full name. +<U>Brian Harvey</U> +Your first name is Brian +Your last name is Harvey +</PRE> + +<P>This program includes two procedures, <CODE>converse</CODE> and +<CODE>halves</CODE>. (A <EM>program</EM> is a bunch of procedures that work +together to achieve a common goal.) <CODE>Converse</CODE> is the <EM> +top-level procedure.</EM> In other +words, <CODE>converse</CODE> is the procedure +that you invoke at the question-mark prompt to set the program in +motion. <CODE>Halves</CODE> is a <EM>subprocedure</EM> of <CODE>converse</CODE>, which +means that <CODE>halves</CODE> is invoked by an instruction inside <CODE> +converse</CODE>. Similarly, <CODE>converse</CODE> is a <EM>superprocedure</EM> of +<CODE>halves</CODE>. + +<P>There are two things you should notice about the terminology "subprocedure" +and "superprocedure." The first thing is that these are <EM>relative</EM> +terms. It doesn't mean anything to say "<CODE>Halves</CODE> is a subprocedure." +Any procedure can be used as part of a larger program. <CODE>Converse</CODE>, +for example, is a superprocedure of <CODE>halves</CODE>, but <CODE>converse</CODE> might at +the same time be a subprocedure of some higher-level procedure we +haven't written yet. The second point is that primitive procedures +can also be considered as subprocedures. For example, <CODE>sentence</CODE> is +a subprocedure of <CODE>halves</CODE>. + +<P>(Now that we're dealing with programs containing more than one defined +procedure, it's a good time for me to remind you that the commands that act +on procedures can accept a list as input as well as a single word. For +example, you can say + +<P><PRE>po [converse halves] +</PRE> + +<P>and Logo will print out the definitions of both procedures.) + +<P>Why are two procedures necessary for this program? When the program +reads your full name, it has to remember the name so that it can print +two parts of it separately. It wouldn't work to say + +<P><PRE>to incorrect.converse +print [Please type your full name.] +print sentence [Your first name is] first readlist +print sentence [Your last name is] last readlist +end +</PRE> + +<P>because each invocation of <CODE>readlist</CODE> would read a separate +line from the keyboard instead of using the same list for both first +and last names. We solve this problem by using the output from <CODE>readlist</CODE> +as the input to a subprocedure of <CODE>converse</CODE> and letting the subprocedure +do the rest of the work. + +<P>One of the examples in Chapter 1 was this procedure: + +<P><PRE>to hi +print [Hi. What's your name?] +print sentence [How are you,] word first readlist "? +ignore readlist +print [That's nice.] +end +</PRE> + +<P><CODE>Hi</CODE> uses a procedure called <CODE>ignore</CODE> that we haven't yet +discussed. <CODE>Ignore</CODE> is predefined in Berkeley Logo but would be easy +enough to define yourself: + +<P><PRE>to ignore :something +end +</PRE> + +<P>That's not a misprint; <CODE>ignore</CODE> really has no instructions +in its definition. <CODE>Ignore</CODE> is a command that takes one input and +has no effect at all! Its purpose is to ignore the +input. In <CODE>hi</CODE>, +the instruction + +<P><PRE>ignore readlist +</PRE> + +<P>waits for you to type a line on the keyboard, then just +ignores whatever you type. (We couldn't just use <CODE>readlist</CODE> as an +instruction all by itself because a complete instruction has to begin +with a command, not an operation. That is, since <CODE>readlist</CODE> +outputs a value, there must be a command to tell Logo what to do with +that value. In this case, we want to <CODE>ignore</CODE> it.) + +<P>»Write a procedure to conjugate the present tense of a regular +first-conjugation (-er) French verb. (Never mind if you don't know what any +of that means! You're about to see.) That is, the letters <CODE>er</CODE> at the +end of the verb should be replaced by a different ending for each pronoun: + +<P><PRE>? <U>conj "jouer</U> +je joue +tu joues +il joue +nous jouons +vous jouez +elles jouent +</PRE> + +<P>The verb <CODE>jouer</CODE> (to play) consists of the root <CODE>jou</CODE> +combined with the infinitive ending <CODE>er</CODE>. Print six +lines, as shown, in which the ending is changed to <CODE>e</CODE>, <CODE>es</CODE>, etc. +Try your procedure on <CODE>monter</CODE> (to climb), <CODE>frapper</CODE> (to hit), and +<CODE>garder</CODE> (to keep). + +<P>By the way, in a practical program we would have to deal with the fact that +French contains many irregular verbs. In addition to wildly irregular ones +like être (to be, irregular even in English) there are ones like manger, +to eat, which are almost regular except that the first and second person +plural forms keep the letter e: nous mangeons. Many issues in natural +language programming (that is, getting computers to speak or understand +human language) turn out like this--90% of the cases are trivial, but most +of your effort goes into the other 10%. + +<P><H2>An Aside on Variable Naming</H2> + +<P>In my metaphor about the frame containing the bus driver's name, the +inscription on the frame tells you what to expect inside the frame. +Variable names like <CODE>person</CODE> and <CODE>name</CODE> serve a similar +purpose. (You might argue that the <CODE>it</CODE> in the group of names +<CODE>him</CODE>, <CODE>her</CODE>, and <CODE>it</CODE> is a little misleading. But it +serves to keep the story straight, probably better than an alternative +like <CODE>him1</CODE> and <CODE>him2</CODE>.) + +<P>Another kind of frame is the one you sometimes see around a car's license +plate: + +<P><CENTER><IMG SRC="mercedes.gif" ALT="figure: mercedes"></CENTER> + +<P>I know it's pedantic to pick apart a joke, but +just the same I want to make the point that this one works only because +the car itself provides enough clues that what belongs in the frame +is indeed a license plate. If you were unfamiliar with the idea of +license plates, that frame wouldn't help you. + +<P>The computer equivalent of this sort of joke is to give your variables +names that don't reflect their purpose in the procedure. Some people +like to name variables after their boyfriends or girlfriends or relatives. +That's okay if you're writing simple programs, like the ones in this +chapter, in which it's very easy to read the program and figure out +what it does. But when you start writing more complicated programs, +you'll need all the help you can get in remembering what each piece +of the program does. I recommend starting early on the habit of using +sensible variable names. + +<P><H2>Don't Call It X</H2> + +<P>Another source of trouble in variable naming is lazy fingers. When +I'm teaching programming classes, a big part of my job is reading +program listings that students bring to me, saying, "I just +can't find the bug in this program." I have an absolute rule that +I refuse to read any program in which there is a variable named <CODE>x</CODE>. + +<P>My students always complain about this arbitrary rule at first. But +more often than not, a student goes through a program +renaming all the variables and then finds that the bug has disappeared! +This magical result comes about because when you use variable names +like <CODE>x</CODE>, you run the risk of using the same name for two different +purposes at the same time. When you pick reasonable names, you'll +pick two different names for the two purposes. + +<P>It is people who've programmed in BASIC who are most likely to make +this mistake. For reasons that aren't very important any more, BASIC +used to <EM>require</EM> single-letter variable names. Even now there +are limits on longer names in most versions of BASIC that make it +risky to use more than two or three letters in a name. So if you're +a BASIC programmer, you've probably gotten into bad habits, which +you should make a point of correcting. + +<P><H2>Writing New Operations</H2> + +<P>So far all the procedures we've written have been commands. That +is, our procedures have had an <EM>effect</EM> (like printing something) +rather than an <EM>output</EM> to be used with other procedures. You +can also write operations, once you know how to give your procedure +an output. Here is an example: + +<P><PRE>to second :thing +output first butfirst :thing +end + +? <U>print second [the red computer]</U> +red +</PRE> + +<P><CODE>Second</CODE> is an operation with one input. Like the primitive +operation <CODE>first</CODE>, it extracts a component of its input, either a character +from a word or a member from a list. However, it outputs the second +component instead of the first one. + +<P>What is new in this procedure definition is the use of the primitive +command <CODE>output</CODE>. <CODE>Output</CODE> can +be used only inside a procedure definition, +not at top level. (In other words, not when you are typing in response +to a question-mark prompt.) It takes one input, which can be any +datum. The effect of <CODE>output</CODE> is to make the datum you supply as +its input be the output from your procedure. + +<P>Some people find it confusing that <CODE>output</CODE> itself is a <EM>command,</EM> +even though a procedure that uses <CODE>output</CODE> is an <EM>operation.</EM> +But it makes sense for <CODE>output</CODE> to be the head of a complete instruction. +The effect of the instruction is to inform Logo what output you want +your procedure (the procedure named <CODE>second</CODE> in this case) to supply. + +<P>Another possible confusion is between <CODE>output</CODE> +and <CODE>print</CODE>. The problem +is that people talk about "computer output" while waving a stack +of paper at you, so you think of "output" as meaning "stuff the +computer printed." But in Logo, "output" is something one procedure +hands to another procedure, not something that is printed. + +<P> +I chose the name <CODE>thing</CODE> for the input to <CODE>second</CODE> to remind +myself that the input can be anything, word or list. <CODE>Thing</CODE> is also, +as you know, the name of a primitive procedure. This is perfectly +okay. The same word can name both a procedure and a variable. Logo +can tell which you mean by the context. A word that is used in an +instruction without punctuation is a procedure name. A word that +is used as an input to the procedure <CODE>thing</CODE> is a variable name. (This +can happen because you put dots in front of the word as an abbreviation +or because you explicitly typed <CODE>thing</CODE> and used the word as its input.) +The expression <CODE>:thing</CODE> is an abbreviation for + +<P><PRE>thing "thing +</PRE> + +<P>in which the first <CODE>thing</CODE> names a procedure, and the +second <CODE>thing</CODE> names a variable. + +<P> + +<P>»Write an operation <CODE>query</CODE> that takes a sentence as input and that +outputs a question formed by swapping the first two words and adding a +question mark to the last word: + +<P><PRE>? <U>print query [I should have known better]</U> +should I have known better? +? <U>print query [you are experienced]</U> +are you experienced? +</PRE> + +<P> + +<H2>Scope of Variables</H2> + +<P>This is going to be a somewhat complicated section, and an important +one, so slow down and read it carefully. + +<P> +When one procedure with inputs invokes another procedure with inputs +as a subprocedure, it's possible for them to share variables and +it's also possible for them to have separate variables. The following +example isn't meant to do anything particularly interesting, just +to make explicit what the rules are. + +<P><PRE>to top :outer :inner +print [I'm in top.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +bottom "x +print [I'm in top again.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +end + +to bottom :inner +print [I'm in bottom.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +end + +? <U>top "a "b</U> +I'm in top. +:outer is a +:inner is b +I'm in bottom. +:outer is a +:inner is x +I'm in top again. +:outer is a +:inner is b +</PRE> + +<P>First, concentrate on the variable named <CODE>outer</CODE>. This name +is used for the first input to <CODE>top</CODE>. <CODE>Bottom</CODE> doesn't have an input +named <CODE>outer</CODE>. When <CODE>bottom</CODE> refers to <CODE>:outer</CODE>, since it doesn't have +one of its own, the reference is to the variable <CODE>outer</CODE> that belongs +to its superprocedure, <CODE>top</CODE>. That's why <CODE>a</CODE> is printed as the value +of <CODE>outer</CODE> in both procedures. + +<P><BLOCKQUOTE> +<STRONG>If a procedure refers to a variable that does not belong to that +procedure, Logo looks for a variable of that name in the superprocedure +of that procedure.</STRONG></BLOCKQUOTE> + +<P>Suppose procedure <CODE>a</CODE> invokes procedure <CODE>b</CODE>, and <CODE>b</CODE> +invokes <CODE>c</CODE>. Suppose an instruction in procedure <CODE>c</CODE> refers +to a variable <CODE>v</CODE>. First Logo tries to find a variable named <CODE>v</CODE> +that belongs to <CODE>c</CODE>. If that fails, Logo looks for a variable +named <CODE>v</CODE> that belongs to procedure <CODE>b</CODE>. Finally, if neither +<CODE>c</CODE> nor <CODE>b</CODE> has a variable named <CODE>v</CODE>, Logo looks for such +a variable that belongs to procedure <CODE>a</CODE>. + +<P> + +<P>Now look at <CODE>inner</CODE>. The important thing to understand is that +<EM>there are two variables named</EM> <CODE>inner</CODE>, one belonging to +each procedure. When <CODE>top</CODE> is invoked, its input named <CODE>inner</CODE> +gets the word <CODE>b</CODE> as its value. When <CODE>top</CODE> invokes <CODE> +bottom</CODE>, <CODE>bottom</CODE>'s input (which is also named <CODE>inner</CODE>) gets +the value <CODE>x</CODE>. But when <CODE>bottom</CODE> finishes, and <CODE>top</CODE> +continues, the name <CODE>inner</CODE> once again refers to the variable +named <CODE>inner</CODE> that belongs to <CODE>top</CODE>. The one that belongs +to <CODE>bottom</CODE> has disappeared. + +<P><BLOCKQUOTE> +<STRONG>Variables that belong to a procedure are temporary. They exist only +so long as that procedure is active. If one procedure has a variable +with the same name as one belonging to its superprocedure, the latter +is temporarily "hidden" while the subprocedure is running. +</STRONG></BLOCKQUOTE> + +<P> +Because each procedure has its own variable named <CODE>inner</CODE>, we refer +to the procedure input variables as <EM>local</EM> to +a particular procedure. +Inputs are always local in Logo. There is also a name for the fact +that a procedure can refer to variables belonging to its superprocedures. +If you want to show off, you can explain to people that Logo has <EM> +dynamic scope,</EM> which is what that rule is called. + +<P> + +<H2>The Little Person Metaphor</H2> + +<P>Earlier I told you my second favorite metaphor about variables. My +very favorite is an old one, which Logo teachers have been +using for years. It is a metaphor about procedures as well as variables, +which is why I didn't present it earlier. Now that you're thinking +about the issue of variable scope, you can see that to have a full +understanding of variables, you have to be thinking about procedures +at the same time. + +<P>The metaphor is that inside the computer there is a large community of +little people. Each person is a specialist at a particular procedure. +So there are <CODE>print</CODE> people and <CODE>butfirst</CODE> people and <CODE> +bottom</CODE> people and <CODE>greet</CODE> people. I like to think of these +people as elves, because I started teaching Logo on a computer +called a PDP-11, and I like the pun of an elf inside an 11. But if +you find elves too cute or childish, perhaps you should think of these +people as doctors in white coats, specializing in dermatology or +ophthalmology or whatever. Another terminology for the same idea, one +which is becoming more and more widely used in advanced computer +science circles, is to call the little people <EM>actors</EM> and to +call their procedures <EM>scripts.</EM> Each actor has only one script, +but several actors can have the same script. + +<P>In any case, what's important is that when a procedure is invoked, +a little person who is an expert on that procedure goes to work. +(It's important that the person is <EM>an expert in</EM> the procedure, +and not the procedure <EM>itself;</EM> we'll see later that there +can be two little people carrying out the same procedure at the same +time. This is one of the more complicated ideas in Logo, so I think +the expert metaphor will help you later.) + +<P>You may be wondering where the variables come in. Well, each elf +is wearing a jerkin, a kind of vest, with a bunch of pockets. (If +your people are doctors, the pockets are in those white lab coats.) +A person has as many pockets as the procedure he or she knows has +inputs. A <CODE>print</CODE> expert has one pocket; a <CODE>sentence</CODE> expert has two. +Each pocket can contain a datum, the value of the variable. (The +pockets are only big enough for a single datum.) Each pocket also +has a name tag sewn on the inside, which contains the name of the +variable. + +<P>The name tags are on the inside to make the point that other people +don't need to know the names of an expert's variables. Other experts +only need to know how many pockets someone has and what kind of thing +to put in them. + +<P>When I typed + +<P><PRE>top "a "b +</PRE> + +<P>the Chief Elf (whose name is Evaluator) found an elf named +Theresa, who is a <CODE>top</CODE> expert, and put an <CODE>a</CODE> in her first pocket and +a <CODE>b</CODE> in her second pocket. + +<P>Theresa's first instruction is + +<P><PRE>print [I'm in top.] +</PRE> + +<P>To carry out that instruction, she handed the list <CODE>[I'm +in top.]</CODE> to another elf named Peter, a <CODE>print</CODE> expert. + +<P>Theresa's second instruction is + +<P><PRE>print sentence [:outer is] :outer +</PRE> + +<P>To carry out this instruction, Theresa wanted to hire Peter +again, but before she could give him his orders, she first had to +deal with Sally, a <CODE>sentence</CODE> expert. (This is the old evaluation story +from Chapter 2 again.) But Theresa didn't know what to put in Sally's +second pocket until she got the information from Tom, a <CODE>thing</CODE> expert. +(Remember that <CODE>:outer</CODE> is an abbreviation for <CODE>thing "outer</CODE>.) + +<P>What's important right now is how Tom does his job. Tom is a sort +of pickpocket. He doesn't steal anything; he just sneaks looks in +other people's pockets. There are lots of people inside the computer, +but the only ones with things in their pockets are the ones who are +actually employed at a given moment. Aside from Tom himself, the +only person who was employed at the time was Theresa, so Tom could +only look in her pockets for a name tag saying <CODE>outer</CODE>. (Theresa is +<EM>planning</EM> to hire Sally and then Peter, to finish carrying out +her instruction, but she can't hire them until she gets the information +she needs from Tom.) + +<P>Later Theresa will hire Bonnie, a <CODE>bottom</CODE> specialist, to help with +the instruction + +<P><PRE>bottom "x +</PRE> + +<P>Theresa will give Bonnie the word <CODE>x</CODE> to put in her pocket. +Bonnie also has an instruction + +<P><PRE>print sentence [:outer is] :outer +</PRE> + +<P>As part of the process of carrying out this instruction, +Bonnie will hire Tom to look for something named <CODE>outer</CODE>. In +that case Tom first looks in the pockets of Bonnie, the person who hired +him. Not finding a pocket named <CODE>outer</CODE>, Tom can <EM>then</EM> +check the pockets of Theresa, the person who hired Bonnie. (If you're +studying Logo in a class with other people, it can be both fun and +instructive to act this out with actual people and pockets.) + +<P><CENTER><IMG SRC="https://people.eecs.berkeley.edu/~bh/v1ch3/elf1.gif" ALT="figure: elf1"></CENTER> + + +<P>An appropriate aspect of this metaphor is that it's slightly rude to look in +someone else's pockets, and you shouldn't do it unnecessarily. This +corresponds to a widely accepted rule of Logo style: most of the time, you +should write procedures so that they don't have to look at variables +belonging to their superprocedures. Whatever information a procedure needs +should be given to it explicitly, as an input. +You'll find situations in which that rule seems very helpful, and other +situations in which taking advantage of dynamic scope seems to make the +program easier to understand. + +<P>»The <CODE>conj</CODE> procedure you wrote earlier deals only with the present +tense of the verb. In French, many other tenses can be formed by a similar +process of replacing the endings, but with different endings for different +tenses. Also, second conjugation (-ir) and third conjugation (-re) verbs +have different endings even in the present tense. You don't want to write +dozens of almost-identical procedures for each of these cases. Instead, +write a single procedure <CODE>superconj</CODE> that takes two inputs, a verb and a +list of six endings, and performs the conjugation: + +<P><PRE>? <U>superconj "jouer [ais ais ait ions iez aient]</U> ; imperfect tense +je jouais +tu jouais +il jouait +nous jouions +vous jouiez +elles jouaient +? <U>superconj "finir [is is it issons issez issent]</U> ; 2nd conj present +je finis +tu finis +il finit +nous finissons +vous finissez +elles finissent +</PRE> + +<P>You can save some typing and take advantage of dynamic scope if +you use a helper procedure. My <CODE>superconj</CODE> looks like this: + +<P><PRE>to superconj :verb :endings +sc1 "je 1 +sc1 "tu 2 +sc1 "il 3 +sc1 "nous 4 +sc1 "vous 5 +sc1 "elles 6 +end +</PRE> + +<P>Write the helper procedure <CODE>sc1</CODE> to finish this. + +<P><H2>Changing the Value of a Variable</H2> + +<P>It is possible for a procedure to change the thing in a variable by +using the <CODE>make</CODE> command. <CODE>Make</CODE> takes two inputs. The first +input must be a word that is the name of a variable, just like the +input to <CODE>thing</CODE>. <CODE>Make</CODE>'s second input can be any datum. +The effect of <CODE>make</CODE> is to make the variable named by its first +input contain as its value the datum that is its second input, +instead of whatever used to be its value. For example, + +<P><PRE>make "inner "y +</PRE> + +<P>would make the variable named <CODE>inner</CODE> have the word <CODE>y</CODE> as its +value. (If there are two variables named <CODE>inner</CODE>, as is the case while +<CODE>bottom</CODE> is running, it is the one in the lower-level procedure that +is changed. This is the same as the rule for <CODE>thing</CODE> that we have +already discussed.) + +<P>Suppose a procedure has variables named <CODE>old</CODE> and <CODE>new</CODE> and you want +to copy the thing in <CODE>old</CODE> into <CODE>new</CODE>. You could say + +<P><PRE>make "new thing "old +</PRE> + +<P>or use the abbreviation + +<P><PRE>make "new :old +</PRE> + +<P>People who don't understand evaluation sometimes get very +upset about the fact that a quotation mark is used to refer to <CODE> +new</CODE> and a colon is used to refer to <CODE>old</CODE>. They think this is +just mumbo-jumbo because they don't understand that a quotation mark +is part of what the colon abbreviates! In both cases we are referring +to the name of a variable. A variable name is a Logo word. To refer +to a word in an instruction and have it evaluate to itself, not invoke +a procedure named <CODE>new</CODE> or <CODE>old</CODE>, the word must be quoted. +The difference is that the first input to <CODE>make</CODE> is the <EM> +name</EM> of the variable we want to change (<CODE>new</CODE>), while the +second input to <CODE>make</CODE> is, in this example, the <EM>value</EM> of a +variable (<CODE>old</CODE>), which we get by invoking <CODE>thing</CODE>. Since you +understand all this, you won't get upset. You also won't resort to +magic formulas like "always use quote for the first variable and +dots for the second" because you understand that the inputs to <CODE> +make</CODE> can be computed with any expression you want! For example, we +could copy <CODE>old</CODE>'s value into <CODE>new</CODE> this way: + +<P><PRE>make first [new old] thing last [new old] +</PRE> + +<P>This instruction contains neither a quotation mark nor a +colon, but the inputs to <CODE>make</CODE> are exactly the same as they were in +the earlier version. + +<P> +Earlier I mentioned that it is considered slightly rude for a procedure +to read its superprocedures' variables. It is <EM>extremely</EM> rude +for a procedure to change the values of other procedures' variables! +Perhaps you can see why that's so. If you're trying to read the definition +of a procedure, and part way through that procedure it invokes a subprocedure, +there is no clue to the fact that the subprocedure changes a variable. +If you break this rule, it makes your program very hard to read because +you have to read all the procedures at once. If each procedure deals +only with its own variables, you have written a <EM>modular</EM> program, +in which each piece can be understood separately. + +<P> + +<H2>Global and Local Variables</H2> + +<P>What if the first input to <CODE>make</CODE> isn't the name of an input to an active +procedure? In other words, what if you try to assign a value to a +variable that doesn't exist? What happens is that a new variable +is created that is <EM>not</EM> local to any procedure. The name for +this kind of variable is a <EM>global</EM> variable. <CODE>Thing</CODE> looks at +global variables if it can't find a local variable with the name you +want. + +<P>A local variable disappears when the procedure it belongs to finishes. +Global variables don't belong to any procedure, so they stay around +forever. This can be convenient, when you have a permanent body of +information that several procedures must use. But it can also lead +to problems if you are careless about what's in which variable. Local +variables come and go with the procedures they belong to, so it's +easy to avoid clutter when you use them. Global variables are more +like old socks under the bed. + +<P>If you are a BASIC programmer, you've become accustomed to a language +in which all variables are global. I've learned over the years that +it's impossible, at this point in your career, for you to appreciate +the profound effect that's had on your style of programming. Only +after you've used procedural languages like Logo for quite a while +will you understand. Meanwhile there is only one hope for you: you +are not allowed to use global variables <EM>at all</EM> for the next few months. +Please take my word for it. + +<P>Sometimes it's convenient for a procedure to use a variable that is +not an input, but which could just as well be local. To do this, you +can use the <CODE>local</CODE> command. This command takes one input, a word. It +creates a variable, local to the procedure that invoked <CODE>local</CODE>, +with that word as its name. For example, we can use <CODE>local</CODE> to +rewrite the earlier <CODE>converse</CODE> example without needing the <CODE> +halves</CODE> subprocedure: + +<P><PRE>to new.converse +local "name +print [Please type your full name.] +make "name readlist +print sentence [Your first name is] first :name +print sentence [Your last name is] last :name +end +</PRE> + +<P>The instruction that invokes <CODE>local</CODE> can be anywhere in the +procedure before the variable is given a value with <CODE>make</CODE>. It's traditional, +though, to put <CODE>local</CODE> instructions at the beginning of a procedure. + +<P>The same procedure would work even without the <CODE>local</CODE>, but then it +would create a global variable named <CODE>name</CODE>. It's much neater if you +can avoid leaving unnecessary global variables around, so you should +use <CODE>local</CODE> unless there is a reason why you really need a global +variable. + +<P> + +<H2>Indirect Assignment</H2> + +<P>Earlier I showed you the example + +<P><PRE>make first [new old] thing last [new old] +</PRE> + +<P>in which the first input to <CODE>make</CODE> was +the result of evaluating a complex expression rather than an explicit +quoted word in the instruction. But the example was kind of silly, +used only to make the point that such a thing is possible. + +<P>Here are a couple of examples in which the use of a computed first +input to <CODE>make</CODE> really makes sense. These are tricky examples; it +may take a couple of readings before you see what I'm doing here. +The technique I'm using is an advanced part of Logo programming. +First is the procedure <CODE>increment</CODE>: + +<P><PRE>to increment :variable +make :variable (thing :variable)+1 +end +</PRE> + +<P>To <EM>increment</EM> a variable means to add something to +it, usually (as in this procedure) to add one to it. The input to +<CODE>increment</CODE> is the name of a variable. The procedure adds 1 to that +variable: + +<P><PRE>? <U>make "count 12</U> +? <U>print :count</U> +12 +? <U>increment "count</U> +? <U>print :count</U> +13 +</PRE> + +<P>You may wonder what the point is. Why couldn't I just say + +<P><PRE>make "count :count+1 +</PRE> + +<P>instead of the obscure <CODE>make</CODE> instruction I used? The +answer is that if we have several variables in the program, each of +which sometimes gets incremented, this technique allows a single +procedure to be able to increment any variable. It's a kind of +shorthand for something we might want to do repeatedly. + +<P>In the definition of <CODE>increment</CODE>, the first input to <CODE>make</CODE> +is not <CODE>"variable</CODE> but rather <CODE>:variable</CODE>. Therefore, the word +<CODE>variable</CODE> itself is not the name of the variable that is incremented. +(To say that more simply, the variable named <CODE>variable</CODE> isn't +incremented.) +Instead the variable named <CODE>variable</CODE> contains as its value the +name of <EM>another</EM> variable. (In the example the value of <CODE> +variable</CODE> is the word <CODE>count</CODE>.) It is that second variable +whose value is changed. +(In the example <CODE>:count</CODE> was 12 and becomes 13.) + +<P>While reading <CODE>increment</CODE>, remember that in the second input to +<CODE>make</CODE>, + +<P><PRE>thing :variable +</PRE> + +<P>is really an abbreviation for + +<P><PRE>thing thing "variable +</PRE> + +<P>In other words this expression asks for the value of the +variable whose name is itself the value of <CODE>variable</CODE>. + +<P>As a second example suppose you're writing a program to play a game +of Tic-Tac-Toe. The computer will play one side and a person can +play the other side. The person gets to choose X or O (that is, going +first or second). The choice might be made with procedures like these: + +<P> +<PRE>to computer.first +make "computer "X +make "person "O +end + +to person.first +make "person "X +make "computer "O +end +</PRE> + +<P>Elsewhere in the program there will be a procedure that +asks the person where he or she wants to move. Suppose the squares +on the board are numbered 1 through 9, and suppose we have two variables, +<CODE>Xsquares</CODE> and <CODE>Osquares</CODE>, which contain lists of numbers corresponding +to the squares marked X and O. Look at this procedure: + +<P><PRE>to person.move :square +make word :person "squares sentence :square thing word :person "squares +end +</PRE> + +<P>The input to <CODE>person.move</CODE> is the number of the square into +which the person has asked to move. The first input to <CODE>make</CODE> is the +expression + +<P><PRE>word :person "squares +</PRE> + +<P>If the person has chosen to move first, then <CODE>:person</CODE> is +the word <CODE>X</CODE>, and the value of this expression is the word <CODE> +Xsquares</CODE>. +If the person has chosen to move last, then <CODE>:person</CODE> is the word <CODE>O</CODE>, +and the value of the expression is the word <CODE>Osquares</CODE>. Either way, +the expression evaluates to the name of the appropriate variable, +into which the newly chosen square is appended. + +<P> + +<P>These are examples of <EM>indirect assignment,</EM> which means assigning +a value to a variable whose name is computed by the program. This +is an unusual, advanced technique. Most of the time you'll use an +explicit quoted word as the first input to <CODE>make</CODE>. But the technique +is a powerful one; many programming languages don't have this capability +at all. In Logo it isn't something that had to be invented specially; +it is a free consequence of the fact that the inputs to any procedure +(including <CODE>make</CODE>) are evaluated before the procedure is invoked. + +<P><H2>Functional Programming</H2> + +<P>But don't get carried away with the flexibility of <CODE>make</CODE>. <EM> +Another</EM> advanced Logo technique avoids the whole idea of changing the +value of a variable. Any procedure that uses <CODE>make</CODE> can be rewritten +to use an input to a subprocedure instead; compare the two versions of the +<CODE>converse</CODE> program in this chapter. + +<P>Why would you want to avoid <CODE>make</CODE>? One reason is that if the value of +a variable changes partway through a procedure, then the sequence of steps +within the procedure is very important. One hot area in computer science +research is <EM>parallel</EM> computation: What if, instead of a computer +that can only do one thing at a time, we build a computer that can do many +things at once? It's hard to take advantage of that ability if each step +of our program depends on the results of previous steps, and if later steps +depend on the result of this one. + +<P>A procedure is <EM>functional</EM> if it always gives the same output when +invoked with the same input(s). We need a few more Logo tools before we can +write interesting functional programs, but we'll come back to this idea soon. + +<P><A HREF="../v1-toc2.html">(back to Table of Contents)</A> +<P><A HREF="https://people.eecs.berkeley.edu/~bh/v1ch2/v1ch2.html"><STRONG>BACK</STRONG></A> +chapter thread <A HREF="../v1ch4/v1ch4.html"><STRONG>NEXT</STRONG></A> + +<P> +<ADDRESS> +<A HREF="../index.html">Brian Harvey</A>, +<CODE>bh@cs.berkeley.edu</CODE> +</ADDRESS> +</BODY> +</HTML> diff --git a/js/games/nluqo.github.io/~bh/v1ch3/variab.html b/js/games/nluqo.github.io/~bh/v1ch3/variab.html new file mode 100644 index 0000000..178b7fe --- /dev/null +++ b/js/games/nluqo.github.io/~bh/v1ch3/variab.html @@ -0,0 +1,1083 @@ +<HTML> +<HEAD> +<TITLE>Computer Science Logo Style vol 1 ch 3: Variables</TITLE> +</HEAD> +<BODY> +<CITE>Computer Science Logo Style</CITE> volume 1: +<CITE>Symbolic Computing</CITE> 2/e Copyright (C) 1997 MIT +<H1>Variables</H1> + +<TABLE width="100%"><TR><TD> +<IMG SRC="../csls1.jpg" ALT="cover photo"> +<TD><TABLE> +<TR><TD align="right"><CITE><A HREF="http://www.cs.berkeley.edu/~bh/">Brian +Harvey</A><BR>University of California, Berkeley</CITE> +<TR><TD align="right"><BR> +<TR><TD align="right"><A HREF="../pdf/v1ch03.pdf">Download PDF version</A> +<TR><TD align="right"><A HREF="../v1-toc2.html">Back to Table of Contents</A> +<TR><TD align="right"><A HREF="https://people.eecs.berkeley.edu/~bh/v1ch2/v1ch2.html"><STRONG>BACK</STRONG></A> +chapter thread <A HREF="../v1ch4/v1ch4.html"><STRONG>NEXT</STRONG></A> +<TR><TD align="right"><A HREF="https://mitpress.mit.edu/books/computer-science-logo-style-second-edition-volume-1">MIT +Press web page for Computer Science Logo Style</A> +</TABLE></TABLE> + +<HR> + +<P> +In the last chapter I suggested that you would find yourself limited +in writing new procedures because your procedures don't take inputs, +so they do exactly the same thing every time you use them. In this +chapter we'll overcome that limitation. + +<P><H2>User Procedures with Inputs</H2> + +<P>As a first example I'm going to write a very simple command named +<CODE>greet</CODE>, which will take a person's name as its one input. Here's how +it will work: + +<P><PRE>? <U>greet "Brian</U> +Hello, Brian +Pleased to meet you. +? <U>greet "Emma</U> +Hello, Emma +Pleased to meet you. +</PRE> + +<P>This procedure will be similar to the <CODE>hello</CODE> command in the +last chapter, except that what it prints will depend on the input +we give it. + +<P> +Each time we <EM>invoke</EM> <CODE>greet</CODE>, we want to give it an input. +So that Logo will expect an input, we must provide for one +when we <EM>define</EM> <CODE>greet</CODE>. (Each procedure has a definite number +of inputs; if <CODE>greet</CODE> takes one input once, it must take one input every +time it's invoked.) Also, in order for the instructions inside <CODE>greet</CODE> +to be able to use the input, we must give the input a <EM>name.</EM> +Both of these needs are met in the <CODE>to</CODE> command that supplies the title +line for the procedure: + +<P><PRE>? <U>to greet :person</U> +</PRE> + +<P>You are already familiar with the use of the <CODE>to</CODE> command, +the need for a word like <CODE>greet</CODE> to name the procedure, and the appearance +of the greater-than prompt instead of the question mark. What's new +here is the use of <CODE>:person</CODE> after the procedure name. This addition +tells Logo that the procedure <CODE>greet</CODE> will require one input and that +the name of the input will be <CODE>person</CODE>. It may help to think of the +input as a container; when the procedure <CODE>greet</CODE> is invoked, something +(such as the word <CODE>Brian</CODE> or the word <CODE>Emma</CODE>) will be put into the +container named <CODE>person</CODE>. + +<P>Why is the colon used in front of the name <CODE>person</CODE>? Remember that +the inputs to <CODE>to</CODE>, unlike the inputs to all other Logo procedures, +are <EM>not</EM> evaluated before <CODE>to</CODE> is invoked. Later we'll see that +a colon has a special meaning to the Logo evaluator, but that special +meaning is <EM>not</EM> in effect in a title line. Instead, the colon +is simply a sort of mnemonic decoration to make a clear distinction +between the word <CODE>greet</CODE>, which is a <EM>procedure</EM> name, and the word +<CODE>person</CODE>, which is an <EM>input</EM> name. Some versions of Logo don't +even require the colon; you can experiment with yours if you're curious. +(By the way, if you want to sound like a Logo maven, you should pronounce +the colon "dots," as in "to greet dots person.") + +<P>To see why having a name for the input is helpful, look at the rest +of the procedure definition: + +<P><PRE>> <U>print sentence "Hello, thing "person</U> +> <U>print [Pleased to meet you.]</U> +> <U>end</U> +? +</PRE> + +<P>You already know about <CODE>print</CODE> and <CODE>sentence</CODE> and about +quoting words with the quotation mark and quoting lists with square +brackets. What's new here is the procedure <CODE>thing</CODE>. + +<P><CODE>Thing</CODE> is an operation. It takes one input, which must be a word +that's the name of a container. The output from <CODE>thing</CODE> +is whatever datum is in the container. + +<P>The technical name for what I've been calling a "container" is a +<EM>variable.</EM> Every variable has a <EM>name</EM> and a <EM>thing</EM> +(or <EM>value</EM>). The name and the thing are both <EM>parts of</EM> the +variable. We'll sometimes speak loosely of "the variable <CODE> +person</CODE>," but you should realize that this <EM>is</EM> speaking +loosely; what we should say is "the variable named <CODE>person</CODE>." +<CODE>Person</CODE> itself is a <EM>word,</EM> which is different from a +variable. + +<P>When I type the instruction + +<P><PRE>greet "Brian +</PRE> + +<P>the Logo interpreter starts with the first word on the line, +<CODE>greet</CODE>. As usual, Logo takes this to be the name of a procedure. +Logo discovers that <CODE>greet</CODE> requires one input, so it continues to the +next thing on the line. This is a quoted word, <CODE>"Brian</CODE>. Since +it's quoted, it requires no further interpretation. The word <CODE>Brian</CODE> +itself becomes the input to <CODE>greet</CODE>.<SUP>*</SUP> + +<P><SMALL><BLOCKQUOTE><SMALL><SUP>*</SUP>While reading the definition +of <CODE>greet</CODE>, it's easy to say "the input is <CODE>person</CODE>"; then, while +reading an invocation of <CODE>greet</CODE>, it's easy to say "the input is <CODE> +Brian</CODE>." To avoid confusion between the input's name and its value, there +are more precise technical terms that we can use when necessary. The name +of the input, given in the title line of the procedure definition, is called +a <EM>formal parameter.</EM> The value of the input, given when the +procedure is invoked, is called an <EM>actual argument.</EM> In +case the actual argument is the result of a more complicated subexpression, +as in the instruction + +<P><PRE>greet first [Brian Harvey] +</PRE> + +<P>we might want to distinguish between the <EM>actual argument +expression,</EM> <CODE>first [Brian Harvey]</CODE>, and the <EM>actual argument +value,</EM> which is the word <CODE>Brian</CODE>.</SMALL></BLOCKQUOTE></SMALL><P>Logo is now ready to invoke <CODE>greet</CODE>. The first step, before +evaluating the instruction lines in <CODE>greet</CODE>, is to create a +variable to hold the input. This variable is given the word <CODE> +person</CODE> as its <EM>name,</EM> and the word <CODE>Brian</CODE> as its <EM> +thing.</EM> (Please notice that I don't have to know the name +of <CODE>greet</CODE>'s input in order to use it. All I have to know is what +<EM>type of thing</EM>--a person's name--<CODE>greet</CODE> expects as its +input. What are the names of the inputs to a primitive like <CODE> +sentence</CODE>? We don't know and we don't need to know.) + +<P>Logo now evaluates the first instruction in <CODE>greet</CODE>. The process +is just like the ones we went through in such detail in Chapter 2. In +the course of this evaluation Logo invokes the procedure <CODE>thing</CODE> +with the word <CODE>person</CODE> as its input. The output from <CODE>thing</CODE> +is the thing in the variable named <CODE>person</CODE>, namely the word <CODE> +Brian</CODE>. That's how the word <CODE>Brian</CODE> becomes one of the inputs to +<CODE>se</CODE>. Here's a plumbing diagram. + +<P><CENTER><IMG SRC="https://people.eecs.berkeley.edu/~bh/v1ch3/varplumb.gif" ALT="figure: varplumb"></CENTER> + +<P><H2>What Kind of Container?</H2> + +<P>One of the favorite activities that Logo experts use to while away +the time when the computer is down is to argue about the best metaphor +to use for variables. A variable is a container, but what kind of +container? + +<P>One popular metaphor is a mailbox. The mailbox has a <EM>name</EM> painted +on it, like "The Smiths." Inside the mailbox is a piece of +mail. The person from the Post Office assigns a <EM>value</EM> to the +box by putting a letter in it. Reading a letter is like invoking +<CODE>thing</CODE> on the mailbox. + +<P>I don't like this metaphor very much, and if I explain why not, it +may help illuminate for you some details about how variables work. +The first problem is that a real mailbox can contain several letters. +A variable can only contain <EM>one</EM> thing or value. (I should say +"one thing at a time," since we'll see that it's possible to replace +the thing in a variable with a different thing.) + +<P>Another problem with the mailbox metaphor is that to read a letter, +you take it out of the mailbox and tear it open. Then it isn't in +the mailbox any more. When you invoke <CODE>thing</CODE> to look at the thing +in a variable, on the other hand, it's still in the variable. You +could use <CODE>thing</CODE> again and get the same answer. + +<P>There are two metaphors that I like. The one I like best won't make +sense for a while, until we talk about scope of variables. +But here is the one I like second best: Sometimes when you take a +bus or a taxi, there is a little frame up in front that looks like +this: + +<P><CENTER><IMG SRC="taxiframe.gif" ALT="figure: taxiframe"></CENTER> + +<P>The phrase "your driver's name is" is like a label for +this frame, and it corresponds to the <EM>name</EM> of a variable. Each +bus driver has a metal or plastic plate that says "John Smith" +or whoever it is. The driver inserts this plate, which corresponds +to the <EM>value</EM> of the variable, into the frame. You can see why +this is a closer metaphor than the mailbox. There is only one plate +in the frame at a time. To find out who's driving the bus, you just +have to look inside the frame; you don't have to remove the plate. + +<P>(To be strictly fair I should tell you that some Logoites +don't like the whole idea of containers. They have a completely different +metaphor, which involves sticking labels on things. But I think it +would only confuse you if I explained that one right now.) + +<P><H2>An Abbreviation</H2> + +<P>Examining the value of a variable is such a common thing to do in +a Logo procedure that there is a special abbreviation for it. Instead +of the expression + +<P><PRE>thing "person +</PRE> + +<P>you can simply say + +<P><PRE>:person +</PRE> + +<P>So in the <CODE>greet</CODE> procedure, we could have said + +<P><PRE>print sentence "hello :person +</PRE> + +<P>Please note that the colon is <EM>not</EM> just an abbreviation +for the word <CODE>thing</CODE> but rather for the combination <CODE>thing</CODE>-quote. + +<P>When drawing plumbing diagrams, treat <CODE>:narf</CODE> as if it were spelled out +as <CODE>thing "narf</CODE>. + +<P><H2>More Procedures</H2> + +<P>It's time to invent more procedures. I'll give you a couple of examples +and you should make up more on your own. + +<P><PRE>to primer :name +print (sentence first :name [is for] word :name ".) +print (sentence "Run, word :name ", "run.) +print (sentence "See :name "run.) +end + +? <U>primer "Paul</U> +P is for Paul. +Run, Paul, run. +See Paul run. +</PRE> + +<P> + +<P><CODE>Primer</CODE> uses the extra-input kludge I mentioned near the +end of Chapter 2. It also shows how the operations <CODE>word</CODE> and +<CODE>sentence</CODE> can be used in combination to punctuate a sentence +properly. + +<P>With all of these examples, incidentally, you should take the time to +work through each instruction line to make sure you understand what +is the input to what. + +<P><PRE>to soap.opera :him :her :it +print (sentence :him "loves word :her ".) +print (sentence "However, :her [doesn't care for] :him "particularly.) +print (sentence :her [is madly in love with] word :it ".) +print (sentence :him [doesn't like] :it [very much.]) +end + +? <U>soap.opera "Bill "Sally "Fred</U> +Bill loves Sally. +However, Sally doesn't care for Bill particularly. +Sally is madly in love with Fred. +Bill doesn't like Fred very much. +</PRE> + +<P> +In this example you see that a procedure can have more than +one input. <CODE>Soap.opera</CODE> has three inputs. You can also see why each +input must have a name, so that the instructions inside the procedure +have a way to refer to the particular input you want to use. You +should also notice that <CODE>soap.opera</CODE> has a period in the middle of its +name, not a space, because the name of a procedure must be a single +Logo word. + +<P> + +<P> +For the next example I'll show how you can write an <EM>interactive</EM> +procedure, which reads something you type on the keyboard. For this +we need a new tool. <CODE>Readlist</CODE> is an operation with no inputs. Its +output is always a list, containing whatever you type on a single +line (up to a RETURN). <CODE>Readlist</CODE> waits for you to type a line, then +outputs what you type. + +<P><PRE>to converse +print [Please type your full name.] +halves readlist +end + +to halves :name +print sentence [Your first name is] first :name +print sentence [Your last name is] last :name +end + +? <U>converse</U> +please type your full name. +<U>Brian Harvey</U> +Your first name is Brian +Your last name is Harvey +</PRE> + +<P>This program includes two procedures, <CODE>converse</CODE> and +<CODE>halves</CODE>. (A <EM>program</EM> is a bunch of procedures that work +together to achieve a common goal.) <CODE>Converse</CODE> is the <EM> +top-level procedure.</EM> In other +words, <CODE>converse</CODE> is the procedure +that you invoke at the question-mark prompt to set the program in +motion. <CODE>Halves</CODE> is a <EM>subprocedure</EM> of <CODE>converse</CODE>, which +means that <CODE>halves</CODE> is invoked by an instruction inside <CODE> +converse</CODE>. Similarly, <CODE>converse</CODE> is a <EM>superprocedure</EM> of +<CODE>halves</CODE>. + +<P>There are two things you should notice about the terminology "subprocedure" +and "superprocedure." The first thing is that these are <EM>relative</EM> +terms. It doesn't mean anything to say "<CODE>Halves</CODE> is a subprocedure." +Any procedure can be used as part of a larger program. <CODE>Converse</CODE>, +for example, is a superprocedure of <CODE>halves</CODE>, but <CODE>converse</CODE> might at +the same time be a subprocedure of some higher-level procedure we +haven't written yet. The second point is that primitive procedures +can also be considered as subprocedures. For example, <CODE>sentence</CODE> is +a subprocedure of <CODE>halves</CODE>. + +<P>(Now that we're dealing with programs containing more than one defined +procedure, it's a good time for me to remind you that the commands that act +on procedures can accept a list as input as well as a single word. For +example, you can say + +<P><PRE>po [converse halves] +</PRE> + +<P>and Logo will print out the definitions of both procedures.) + +<P>Why are two procedures necessary for this program? When the program +reads your full name, it has to remember the name so that it can print +two parts of it separately. It wouldn't work to say + +<P><PRE>to incorrect.converse +print [Please type your full name.] +print sentence [Your first name is] first readlist +print sentence [Your last name is] last readlist +end +</PRE> + +<P>because each invocation of <CODE>readlist</CODE> would read a separate +line from the keyboard instead of using the same list for both first +and last names. We solve this problem by using the output from <CODE>readlist</CODE> +as the input to a subprocedure of <CODE>converse</CODE> and letting the subprocedure +do the rest of the work. + +<P>One of the examples in Chapter 1 was this procedure: + +<P><PRE>to hi +print [Hi. What's your name?] +print sentence [How are you,] word first readlist "? +ignore readlist +print [That's nice.] +end +</PRE> + +<P><CODE>Hi</CODE> uses a procedure called <CODE>ignore</CODE> that we haven't yet +discussed. <CODE>Ignore</CODE> is predefined in Berkeley Logo but would be easy +enough to define yourself: + +<P><PRE>to ignore :something +end +</PRE> + +<P>That's not a misprint; <CODE>ignore</CODE> really has no instructions +in its definition. <CODE>Ignore</CODE> is a command that takes one input and +has no effect at all! Its purpose is to ignore the +input. In <CODE>hi</CODE>, +the instruction + +<P><PRE>ignore readlist +</PRE> + +<P>waits for you to type a line on the keyboard, then just +ignores whatever you type. (We couldn't just use <CODE>readlist</CODE> as an +instruction all by itself because a complete instruction has to begin +with a command, not an operation. That is, since <CODE>readlist</CODE> +outputs a value, there must be a command to tell Logo what to do with +that value. In this case, we want to <CODE>ignore</CODE> it.) + +<P>»Write a procedure to conjugate the present tense of a regular +first-conjugation (-er) French verb. (Never mind if you don't know what any +of that means! You're about to see.) That is, the letters <CODE>er</CODE> at the +end of the verb should be replaced by a different ending for each pronoun: + +<P><PRE>? <U>conj "jouer</U> +je joue +tu joues +il joue +nous jouons +vous jouez +elles jouent +</PRE> + +<P>The verb <CODE>jouer</CODE> (to play) consists of the root <CODE>jou</CODE> +combined with the infinitive ending <CODE>er</CODE>. Print six +lines, as shown, in which the ending is changed to <CODE>e</CODE>, <CODE>es</CODE>, etc. +Try your procedure on <CODE>monter</CODE> (to climb), <CODE>frapper</CODE> (to hit), and +<CODE>garder</CODE> (to keep). + +<P>By the way, in a practical program we would have to deal with the fact that +French contains many irregular verbs. In addition to wildly irregular ones +like être (to be, irregular even in English) there are ones like manger, +to eat, which are almost regular except that the first and second person +plural forms keep the letter e: nous mangeons. Many issues in natural +language programming (that is, getting computers to speak or understand +human language) turn out like this--90% of the cases are trivial, but most +of your effort goes into the other 10%. + +<P><H2>An Aside on Variable Naming</H2> + +<P>In my metaphor about the frame containing the bus driver's name, the +inscription on the frame tells you what to expect inside the frame. +Variable names like <CODE>person</CODE> and <CODE>name</CODE> serve a similar +purpose. (You might argue that the <CODE>it</CODE> in the group of names +<CODE>him</CODE>, <CODE>her</CODE>, and <CODE>it</CODE> is a little misleading. But it +serves to keep the story straight, probably better than an alternative +like <CODE>him1</CODE> and <CODE>him2</CODE>.) + +<P>Another kind of frame is the one you sometimes see around a car's license +plate: + +<P><CENTER><IMG SRC="mercedes.gif" ALT="figure: mercedes"></CENTER> + +<P>I know it's pedantic to pick apart a joke, but +just the same I want to make the point that this one works only because +the car itself provides enough clues that what belongs in the frame +is indeed a license plate. If you were unfamiliar with the idea of +license plates, that frame wouldn't help you. + +<P>The computer equivalent of this sort of joke is to give your variables +names that don't reflect their purpose in the procedure. Some people +like to name variables after their boyfriends or girlfriends or relatives. +That's okay if you're writing simple programs, like the ones in this +chapter, in which it's very easy to read the program and figure out +what it does. But when you start writing more complicated programs, +you'll need all the help you can get in remembering what each piece +of the program does. I recommend starting early on the habit of using +sensible variable names. + +<P><H2>Don't Call It X</H2> + +<P>Another source of trouble in variable naming is lazy fingers. When +I'm teaching programming classes, a big part of my job is reading +program listings that students bring to me, saying, "I just +can't find the bug in this program." I have an absolute rule that +I refuse to read any program in which there is a variable named <CODE>x</CODE>. + +<P>My students always complain about this arbitrary rule at first. But +more often than not, a student goes through a program +renaming all the variables and then finds that the bug has disappeared! +This magical result comes about because when you use variable names +like <CODE>x</CODE>, you run the risk of using the same name for two different +purposes at the same time. When you pick reasonable names, you'll +pick two different names for the two purposes. + +<P>It is people who've programmed in BASIC who are most likely to make +this mistake. For reasons that aren't very important any more, BASIC +used to <EM>require</EM> single-letter variable names. Even now there +are limits on longer names in most versions of BASIC that make it +risky to use more than two or three letters in a name. So if you're +a BASIC programmer, you've probably gotten into bad habits, which +you should make a point of correcting. + +<P><H2>Writing New Operations</H2> + +<P>So far all the procedures we've written have been commands. That +is, our procedures have had an <EM>effect</EM> (like printing something) +rather than an <EM>output</EM> to be used with other procedures. You +can also write operations, once you know how to give your procedure +an output. Here is an example: + +<P><PRE>to second :thing +output first butfirst :thing +end + +? <U>print second [the red computer]</U> +red +</PRE> + +<P><CODE>Second</CODE> is an operation with one input. Like the primitive +operation <CODE>first</CODE>, it extracts a component of its input, either a character +from a word or a member from a list. However, it outputs the second +component instead of the first one. + +<P>What is new in this procedure definition is the use of the primitive +command <CODE>output</CODE>. <CODE>Output</CODE> can +be used only inside a procedure definition, +not at top level. (In other words, not when you are typing in response +to a question-mark prompt.) It takes one input, which can be any +datum. The effect of <CODE>output</CODE> is to make the datum you supply as +its input be the output from your procedure. + +<P>Some people find it confusing that <CODE>output</CODE> itself is a <EM>command,</EM> +even though a procedure that uses <CODE>output</CODE> is an <EM>operation.</EM> +But it makes sense for <CODE>output</CODE> to be the head of a complete instruction. +The effect of the instruction is to inform Logo what output you want +your procedure (the procedure named <CODE>second</CODE> in this case) to supply. + +<P>Another possible confusion is between <CODE>output</CODE> +and <CODE>print</CODE>. The problem +is that people talk about "computer output" while waving a stack +of paper at you, so you think of "output" as meaning "stuff the +computer printed." But in Logo, "output" is something one procedure +hands to another procedure, not something that is printed. + +<P> +I chose the name <CODE>thing</CODE> for the input to <CODE>second</CODE> to remind +myself that the input can be anything, word or list. <CODE>Thing</CODE> is also, +as you know, the name of a primitive procedure. This is perfectly +okay. The same word can name both a procedure and a variable. Logo +can tell which you mean by the context. A word that is used in an +instruction without punctuation is a procedure name. A word that +is used as an input to the procedure <CODE>thing</CODE> is a variable name. (This +can happen because you put dots in front of the word as an abbreviation +or because you explicitly typed <CODE>thing</CODE> and used the word as its input.) +The expression <CODE>:thing</CODE> is an abbreviation for + +<P><PRE>thing "thing +</PRE> + +<P>in which the first <CODE>thing</CODE> names a procedure, and the +second <CODE>thing</CODE> names a variable. + +<P> + +<P>»Write an operation <CODE>query</CODE> that takes a sentence as input and that +outputs a question formed by swapping the first two words and adding a +question mark to the last word: + +<P><PRE>? <U>print query [I should have known better]</U> +should I have known better? +? <U>print query [you are experienced]</U> +are you experienced? +</PRE> + +<P> + +<H2>Scope of Variables</H2> + +<P>This is going to be a somewhat complicated section, and an important +one, so slow down and read it carefully. + +<P> +When one procedure with inputs invokes another procedure with inputs +as a subprocedure, it's possible for them to share variables and +it's also possible for them to have separate variables. The following +example isn't meant to do anything particularly interesting, just +to make explicit what the rules are. + +<P><PRE>to top :outer :inner +print [I'm in top.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +bottom "x +print [I'm in top again.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +end + +to bottom :inner +print [I'm in bottom.] +print sentence [:outer is] :outer +print sentence [:inner is] :inner +end + +? <U>top "a "b</U> +I'm in top. +:outer is a +:inner is b +I'm in bottom. +:outer is a +:inner is x +I'm in top again. +:outer is a +:inner is b +</PRE> + +<P>First, concentrate on the variable named <CODE>outer</CODE>. This name +is used for the first input to <CODE>top</CODE>. <CODE>Bottom</CODE> doesn't have an input +named <CODE>outer</CODE>. When <CODE>bottom</CODE> refers to <CODE>:outer</CODE>, since it doesn't have +one of its own, the reference is to the variable <CODE>outer</CODE> that belongs +to its superprocedure, <CODE>top</CODE>. That's why <CODE>a</CODE> is printed as the value +of <CODE>outer</CODE> in both procedures. + +<P><BLOCKQUOTE> +<STRONG>If a procedure refers to a variable that does not belong to that +procedure, Logo looks for a variable of that name in the superprocedure +of that procedure.</STRONG></BLOCKQUOTE> + +<P>Suppose procedure <CODE>a</CODE> invokes procedure <CODE>b</CODE>, and <CODE>b</CODE> +invokes <CODE>c</CODE>. Suppose an instruction in procedure <CODE>c</CODE> refers +to a variable <CODE>v</CODE>. First Logo tries to find a variable named <CODE>v</CODE> +that belongs to <CODE>c</CODE>. If that fails, Logo looks for a variable +named <CODE>v</CODE> that belongs to procedure <CODE>b</CODE>. Finally, if neither +<CODE>c</CODE> nor <CODE>b</CODE> has a variable named <CODE>v</CODE>, Logo looks for such +a variable that belongs to procedure <CODE>a</CODE>. + +<P> + +<P>Now look at <CODE>inner</CODE>. The important thing to understand is that +<EM>there are two variables named</EM> <CODE>inner</CODE>, one belonging to +each procedure. When <CODE>top</CODE> is invoked, its input named <CODE>inner</CODE> +gets the word <CODE>b</CODE> as its value. When <CODE>top</CODE> invokes <CODE> +bottom</CODE>, <CODE>bottom</CODE>'s input (which is also named <CODE>inner</CODE>) gets +the value <CODE>x</CODE>. But when <CODE>bottom</CODE> finishes, and <CODE>top</CODE> +continues, the name <CODE>inner</CODE> once again refers to the variable +named <CODE>inner</CODE> that belongs to <CODE>top</CODE>. The one that belongs +to <CODE>bottom</CODE> has disappeared. + +<P><BLOCKQUOTE> +<STRONG>Variables that belong to a procedure are temporary. They exist only +so long as that procedure is active. If one procedure has a variable +with the same name as one belonging to its superprocedure, the latter +is temporarily "hidden" while the subprocedure is running. +</STRONG></BLOCKQUOTE> + +<P> +Because each procedure has its own variable named <CODE>inner</CODE>, we refer +to the procedure input variables as <EM>local</EM> to +a particular procedure. +Inputs are always local in Logo. There is also a name for the fact +that a procedure can refer to variables belonging to its superprocedures. +If you want to show off, you can explain to people that Logo has <EM> +dynamic scope,</EM> which is what that rule is called. + +<P> + +<H2>The Little Person Metaphor</H2> + +<P>Earlier I told you my second favorite metaphor about variables. My +very favorite is an old one, which Logo teachers have been +using for years. It is a metaphor about procedures as well as variables, +which is why I didn't present it earlier. Now that you're thinking +about the issue of variable scope, you can see that to have a full +understanding of variables, you have to be thinking about procedures +at the same time. + +<P>The metaphor is that inside the computer there is a large community of +little people. Each person is a specialist at a particular procedure. +So there are <CODE>print</CODE> people and <CODE>butfirst</CODE> people and <CODE> +bottom</CODE> people and <CODE>greet</CODE> people. I like to think of these +people as elves, because I started teaching Logo on a computer +called a PDP-11, and I like the pun of an elf inside an 11. But if +you find elves too cute or childish, perhaps you should think of these +people as doctors in white coats, specializing in dermatology or +ophthalmology or whatever. Another terminology for the same idea, one +which is becoming more and more widely used in advanced computer +science circles, is to call the little people <EM>actors</EM> and to +call their procedures <EM>scripts.</EM> Each actor has only one script, +but several actors can have the same script. + +<P>In any case, what's important is that when a procedure is invoked, +a little person who is an expert on that procedure goes to work. +(It's important that the person is <EM>an expert in</EM> the procedure, +and not the procedure <EM>itself;</EM> we'll see later that there +can be two little people carrying out the same procedure at the same +time. This is one of the more complicated ideas in Logo, so I think +the expert metaphor will help you later.) + +<P>You may be wondering where the variables come in. Well, each elf +is wearing a jerkin, a kind of vest, with a bunch of pockets. (If +your people are doctors, the pockets are in those white lab coats.) +A person has as many pockets as the procedure he or she knows has +inputs. A <CODE>print</CODE> expert has one pocket; a <CODE>sentence</CODE> expert has two. +Each pocket can contain a datum, the value of the variable. (The +pockets are only big enough for a single datum.) Each pocket also +has a name tag sewn on the inside, which contains the name of the +variable. + +<P>The name tags are on the inside to make the point that other people +don't need to know the names of an expert's variables. Other experts +only need to know how many pockets someone has and what kind of thing +to put in them. + +<P>When I typed + +<P><PRE>top "a "b +</PRE> + +<P>the Chief Elf (whose name is Evaluator) found an elf named +Theresa, who is a <CODE>top</CODE> expert, and put an <CODE>a</CODE> in her first pocket and +a <CODE>b</CODE> in her second pocket. + +<P>Theresa's first instruction is + +<P><PRE>print [I'm in top.] +</PRE> + +<P>To carry out that instruction, she handed the list <CODE>[I'm +in top.]</CODE> to another elf named Peter, a <CODE>print</CODE> expert. + +<P>Theresa's second instruction is + +<P><PRE>print sentence [:outer is] :outer +</PRE> + +<P>To carry out this instruction, Theresa wanted to hire Peter +again, but before she could give him his orders, she first had to +deal with Sally, a <CODE>sentence</CODE> expert. (This is the old evaluation story +from Chapter 2 again.) But Theresa didn't know what to put in Sally's +second pocket until she got the information from Tom, a <CODE>thing</CODE> expert. +(Remember that <CODE>:outer</CODE> is an abbreviation for <CODE>thing "outer</CODE>.) + +<P>What's important right now is how Tom does his job. Tom is a sort +of pickpocket. He doesn't steal anything; he just sneaks looks in +other people's pockets. There are lots of people inside the computer, +but the only ones with things in their pockets are the ones who are +actually employed at a given moment. Aside from Tom himself, the +only person who was employed at the time was Theresa, so Tom could +only look in her pockets for a name tag saying <CODE>outer</CODE>. (Theresa is +<EM>planning</EM> to hire Sally and then Peter, to finish carrying out +her instruction, but she can't hire them until she gets the information +she needs from Tom.) + +<P>Later Theresa will hire Bonnie, a <CODE>bottom</CODE> specialist, to help with +the instruction + +<P><PRE>bottom "x +</PRE> + +<P>Theresa will give Bonnie the word <CODE>x</CODE> to put in her pocket. +Bonnie also has an instruction + +<P><PRE>print sentence [:outer is] :outer +</PRE> + +<P>As part of the process of carrying out this instruction, +Bonnie will hire Tom to look for something named <CODE>outer</CODE>. In +that case Tom first looks in the pockets of Bonnie, the person who hired +him. Not finding a pocket named <CODE>outer</CODE>, Tom can <EM>then</EM> +check the pockets of Theresa, the person who hired Bonnie. (If you're +studying Logo in a class with other people, it can be both fun and +instructive to act this out with actual people and pockets.) + +<P><CENTER><IMG SRC="https://people.eecs.berkeley.edu/~bh/v1ch3/elf1.gif" ALT="figure: elf1"></CENTER> + + +<P>An appropriate aspect of this metaphor is that it's slightly rude to look in +someone else's pockets, and you shouldn't do it unnecessarily. This +corresponds to a widely accepted rule of Logo style: most of the time, you +should write procedures so that they don't have to look at variables +belonging to their superprocedures. Whatever information a procedure needs +should be given to it explicitly, as an input. +You'll find situations in which that rule seems very helpful, and other +situations in which taking advantage of dynamic scope seems to make the +program easier to understand. + +<P>»The <CODE>conj</CODE> procedure you wrote earlier deals only with the present +tense of the verb. In French, many other tenses can be formed by a similar +process of replacing the endings, but with different endings for different +tenses. Also, second conjugation (-ir) and third conjugation (-re) verbs +have different endings even in the present tense. You don't want to write +dozens of almost-identical procedures for each of these cases. Instead, +write a single procedure <CODE>superconj</CODE> that takes two inputs, a verb and a +list of six endings, and performs the conjugation: + +<P><PRE>? <U>superconj "jouer [ais ais ait ions iez aient]</U> ; imperfect tense +je jouais +tu jouais +il jouait +nous jouions +vous jouiez +elles jouaient +? <U>superconj "finir [is is it issons issez issent]</U> ; 2nd conj present +je finis +tu finis +il finit +nous finissons +vous finissez +elles finissent +</PRE> + +<P>You can save some typing and take advantage of dynamic scope if +you use a helper procedure. My <CODE>superconj</CODE> looks like this: + +<P><PRE>to superconj :verb :endings +sc1 "je 1 +sc1 "tu 2 +sc1 "il 3 +sc1 "nous 4 +sc1 "vous 5 +sc1 "elles 6 +end +</PRE> + +<P>Write the helper procedure <CODE>sc1</CODE> to finish this. + +<P><H2>Changing the Value of a Variable</H2> + +<P>It is possible for a procedure to change the thing in a variable by +using the <CODE>make</CODE> command. <CODE>Make</CODE> takes two inputs. The first +input must be a word that is the name of a variable, just like the +input to <CODE>thing</CODE>. <CODE>Make</CODE>'s second input can be any datum. +The effect of <CODE>make</CODE> is to make the variable named by its first +input contain as its value the datum that is its second input, +instead of whatever used to be its value. For example, + +<P><PRE>make "inner "y +</PRE> + +<P>would make the variable named <CODE>inner</CODE> have the word <CODE>y</CODE> as its +value. (If there are two variables named <CODE>inner</CODE>, as is the case while +<CODE>bottom</CODE> is running, it is the one in the lower-level procedure that +is changed. This is the same as the rule for <CODE>thing</CODE> that we have +already discussed.) + +<P>Suppose a procedure has variables named <CODE>old</CODE> and <CODE>new</CODE> and you want +to copy the thing in <CODE>old</CODE> into <CODE>new</CODE>. You could say + +<P><PRE>make "new thing "old +</PRE> + +<P>or use the abbreviation + +<P><PRE>make "new :old +</PRE> + +<P>People who don't understand evaluation sometimes get very +upset about the fact that a quotation mark is used to refer to <CODE> +new</CODE> and a colon is used to refer to <CODE>old</CODE>. They think this is +just mumbo-jumbo because they don't understand that a quotation mark +is part of what the colon abbreviates! In both cases we are referring +to the name of a variable. A variable name is a Logo word. To refer +to a word in an instruction and have it evaluate to itself, not invoke +a procedure named <CODE>new</CODE> or <CODE>old</CODE>, the word must be quoted. +The difference is that the first input to <CODE>make</CODE> is the <EM> +name</EM> of the variable we want to change (<CODE>new</CODE>), while the +second input to <CODE>make</CODE> is, in this example, the <EM>value</EM> of a +variable (<CODE>old</CODE>), which we get by invoking <CODE>thing</CODE>. Since you +understand all this, you won't get upset. You also won't resort to +magic formulas like "always use quote for the first variable and +dots for the second" because you understand that the inputs to <CODE> +make</CODE> can be computed with any expression you want! For example, we +could copy <CODE>old</CODE>'s value into <CODE>new</CODE> this way: + +<P><PRE>make first [new old] thing last [new old] +</PRE> + +<P>This instruction contains neither a quotation mark nor a +colon, but the inputs to <CODE>make</CODE> are exactly the same as they were in +the earlier version. + +<P> +Earlier I mentioned that it is considered slightly rude for a procedure +to read its superprocedures' variables. It is <EM>extremely</EM> rude +for a procedure to change the values of other procedures' variables! +Perhaps you can see why that's so. If you're trying to read the definition +of a procedure, and part way through that procedure it invokes a subprocedure, +there is no clue to the fact that the subprocedure changes a variable. +If you break this rule, it makes your program very hard to read because +you have to read all the procedures at once. If each procedure deals +only with its own variables, you have written a <EM>modular</EM> program, +in which each piece can be understood separately. + +<P> + +<H2>Global and Local Variables</H2> + +<P>What if the first input to <CODE>make</CODE> isn't the name of an input to an active +procedure? In other words, what if you try to assign a value to a +variable that doesn't exist? What happens is that a new variable +is created that is <EM>not</EM> local to any procedure. The name for +this kind of variable is a <EM>global</EM> variable. <CODE>Thing</CODE> looks at +global variables if it can't find a local variable with the name you +want. + +<P>A local variable disappears when the procedure it belongs to finishes. +Global variables don't belong to any procedure, so they stay around +forever. This can be convenient, when you have a permanent body of +information that several procedures must use. But it can also lead +to problems if you are careless about what's in which variable. Local +variables come and go with the procedures they belong to, so it's +easy to avoid clutter when you use them. Global variables are more +like old socks under the bed. + +<P>If you are a BASIC programmer, you've become accustomed to a language +in which all variables are global. I've learned over the years that +it's impossible, at this point in your career, for you to appreciate +the profound effect that's had on your style of programming. Only +after you've used procedural languages like Logo for quite a while +will you understand. Meanwhile there is only one hope for you: you +are not allowed to use global variables <EM>at all</EM> for the next few months. +Please take my word for it. + +<P>Sometimes it's convenient for a procedure to use a variable that is +not an input, but which could just as well be local. To do this, you +can use the <CODE>local</CODE> command. This command takes one input, a word. It +creates a variable, local to the procedure that invoked <CODE>local</CODE>, +with that word as its name. For example, we can use <CODE>local</CODE> to +rewrite the earlier <CODE>converse</CODE> example without needing the <CODE> +halves</CODE> subprocedure: + +<P><PRE>to new.converse +local "name +print [Please type your full name.] +make "name readlist +print sentence [Your first name is] first :name +print sentence [Your last name is] last :name +end +</PRE> + +<P>The instruction that invokes <CODE>local</CODE> can be anywhere in the +procedure before the variable is given a value with <CODE>make</CODE>. It's traditional, +though, to put <CODE>local</CODE> instructions at the beginning of a procedure. + +<P>The same procedure would work even without the <CODE>local</CODE>, but then it +would create a global variable named <CODE>name</CODE>. It's much neater if you +can avoid leaving unnecessary global variables around, so you should +use <CODE>local</CODE> unless there is a reason why you really need a global +variable. + +<P> + +<H2>Indirect Assignment</H2> + +<P>Earlier I showed you the example + +<P><PRE>make first [new old] thing last [new old] +</PRE> + +<P>in which the first input to <CODE>make</CODE> was +the result of evaluating a complex expression rather than an explicit +quoted word in the instruction. But the example was kind of silly, +used only to make the point that such a thing is possible. + +<P>Here are a couple of examples in which the use of a computed first +input to <CODE>make</CODE> really makes sense. These are tricky examples; it +may take a couple of readings before you see what I'm doing here. +The technique I'm using is an advanced part of Logo programming. +First is the procedure <CODE>increment</CODE>: + +<P><PRE>to increment :variable +make :variable (thing :variable)+1 +end +</PRE> + +<P>To <EM>increment</EM> a variable means to add something to +it, usually (as in this procedure) to add one to it. The input to +<CODE>increment</CODE> is the name of a variable. The procedure adds 1 to that +variable: + +<P><PRE>? <U>make "count 12</U> +? <U>print :count</U> +12 +? <U>increment "count</U> +? <U>print :count</U> +13 +</PRE> + +<P>You may wonder what the point is. Why couldn't I just say + +<P><PRE>make "count :count+1 +</PRE> + +<P>instead of the obscure <CODE>make</CODE> instruction I used? The +answer is that if we have several variables in the program, each of +which sometimes gets incremented, this technique allows a single +procedure to be able to increment any variable. It's a kind of +shorthand for something we might want to do repeatedly. + +<P>In the definition of <CODE>increment</CODE>, the first input to <CODE>make</CODE> +is not <CODE>"variable</CODE> but rather <CODE>:variable</CODE>. Therefore, the word +<CODE>variable</CODE> itself is not the name of the variable that is incremented. +(To say that more simply, the variable named <CODE>variable</CODE> isn't +incremented.) +Instead the variable named <CODE>variable</CODE> contains as its value the +name of <EM>another</EM> variable. (In the example the value of <CODE> +variable</CODE> is the word <CODE>count</CODE>.) It is that second variable +whose value is changed. +(In the example <CODE>:count</CODE> was 12 and becomes 13.) + +<P>While reading <CODE>increment</CODE>, remember that in the second input to +<CODE>make</CODE>, + +<P><PRE>thing :variable +</PRE> + +<P>is really an abbreviation for + +<P><PRE>thing thing "variable +</PRE> + +<P>In other words this expression asks for the value of the +variable whose name is itself the value of <CODE>variable</CODE>. + +<P>As a second example suppose you're writing a program to play a game +of Tic-Tac-Toe. The computer will play one side and a person can +play the other side. The person gets to choose X or O (that is, going +first or second). The choice might be made with procedures like these: + +<P> +<PRE>to computer.first +make "computer "X +make "person "O +end + +to person.first +make "person "X +make "computer "O +end +</PRE> + +<P>Elsewhere in the program there will be a procedure that +asks the person where he or she wants to move. Suppose the squares +on the board are numbered 1 through 9, and suppose we have two variables, +<CODE>Xsquares</CODE> and <CODE>Osquares</CODE>, which contain lists of numbers corresponding +to the squares marked X and O. Look at this procedure: + +<P><PRE>to person.move :square +make word :person "squares sentence :square thing word :person "squares +end +</PRE> + +<P>The input to <CODE>person.move</CODE> is the number of the square into +which the person has asked to move. The first input to <CODE>make</CODE> is the +expression + +<P><PRE>word :person "squares +</PRE> + +<P>If the person has chosen to move first, then <CODE>:person</CODE> is +the word <CODE>X</CODE>, and the value of this expression is the word <CODE> +Xsquares</CODE>. +If the person has chosen to move last, then <CODE>:person</CODE> is the word <CODE>O</CODE>, +and the value of the expression is the word <CODE>Osquares</CODE>. Either way, +the expression evaluates to the name of the appropriate variable, +into which the newly chosen square is appended. + +<P> + +<P>These are examples of <EM>indirect assignment,</EM> which means assigning +a value to a variable whose name is computed by the program. This +is an unusual, advanced technique. Most of the time you'll use an +explicit quoted word as the first input to <CODE>make</CODE>. But the technique +is a powerful one; many programming languages don't have this capability +at all. In Logo it isn't something that had to be invented specially; +it is a free consequence of the fact that the inputs to any procedure +(including <CODE>make</CODE>) are evaluated before the procedure is invoked. + +<P><H2>Functional Programming</H2> + +<P>But don't get carried away with the flexibility of <CODE>make</CODE>. <EM> +Another</EM> advanced Logo technique avoids the whole idea of changing the +value of a variable. Any procedure that uses <CODE>make</CODE> can be rewritten +to use an input to a subprocedure instead; compare the two versions of the +<CODE>converse</CODE> program in this chapter. + +<P>Why would you want to avoid <CODE>make</CODE>? One reason is that if the value of +a variable changes partway through a procedure, then the sequence of steps +within the procedure is very important. One hot area in computer science +research is <EM>parallel</EM> computation: What if, instead of a computer +that can only do one thing at a time, we build a computer that can do many +things at once? It's hard to take advantage of that ability if each step +of our program depends on the results of previous steps, and if later steps +depend on the result of this one. + +<P>A procedure is <EM>functional</EM> if it always gives the same output when +invoked with the same input(s). We need a few more Logo tools before we can +write interesting functional programs, but we'll come back to this idea soon. + +<P><A HREF="../v1-toc2.html">(back to Table of Contents)</A> +<P><A HREF="https://people.eecs.berkeley.edu/~bh/v1ch2/v1ch2.html"><STRONG>BACK</STRONG></A> +chapter thread <A HREF="../v1ch4/v1ch4.html"><STRONG>NEXT</STRONG></A> + +<P> +<ADDRESS> +<A HREF="../index.html">Brian Harvey</A>, +<CODE>bh@cs.berkeley.edu</CODE> +</ADDRESS> +</BODY> +</HTML> |