about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
committerelioat <elioat@tilde.institute>2023-08-23 07:52:19 -0400
commit562a9a52d599d9a05f871404050968a5fd282640 (patch)
tree7d3305c1252c043bfe246ccc7deff0056aa6b5ab /js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html
parent5d012c6c011a9dedf7d0a098e456206244eb5a0f (diff)
downloadtour-562a9a52d599d9a05f871404050968a5fd282640.tar.gz
*
Diffstat (limited to 'js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html')
-rw-r--r--js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html830
1 files changed, 830 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html b/js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html
new file mode 100644
index 0000000..c36950f
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/v1ch4/v1ch4.html
@@ -0,0 +1,830 @@
+<HTML>
+<HEAD>
+<TITLE>Computer Science Logo Style vol 1 ch 4: Predicates</TITLE>
+</HEAD>
+<BODY>
+<CITE>Computer Science Logo Style</CITE> volume 1:
+<CITE>Symbolic Computing</CITE> 2/e Copyright (C) 1997 MIT
+<H1>Predicates</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/v1ch04.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="../v1ch3/v1ch3.html"><STRONG>BACK</STRONG></A>
+chapter thread <A HREF="../v1ch5/v1ch5.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>
+By introducing variables in Chapter 3, we made it possible for a
+procedure to operate on different data each time you invoke it.  But
+the <EM>pattern</EM> of what the procedure does with the data remains
+constant.  We can get even more variety out of our procedures if we
+can vary the <EM>instructions</EM> that the procedure executes.  We
+need a way to say, &quot;Sometimes do this; other times do that.&quot;
+
+<P><H2>True or False</H2>
+
+<P>One helpful metaphor is this:  When you invoke a command, you're giving
+the computer an order.  &quot;Now hear this!  <CODE>Print</CODE> such-and-such!&quot;
+But when you invoke an operation, you're asking the computer a <EM>
+question.</EM>  &quot;What is the <CODE>first</CODE> member of such-and-such?&quot;
+
+<P>In real life we single out as a special category <EM>
+yes-or-no questions.</EM>
+For example, these special questions form the basis of the
+game Twenty Questions.  The corresponding
+category in Logo is the <EM>predicate.</EM>
+A predicate is an operation whose output is always either the word
+<CODE>true</CODE> or the word <CODE>false</CODE>.
+
+<P>For example, <CODE>listp</CODE> (pronounced &quot;list-pea&quot;) is a predicate
+that takes one input.  The input can be any datum.  The output from
+<CODE>listp</CODE> is <CODE>true</CODE> if the input is a list, <CODE>false</CODE> if the
+input is a word.
+
+<P><CODE>Wordp</CODE> is another predicate that takes one input.  The input can
+be any datum.  The output from <CODE>wordp</CODE> is <CODE>true</CODE> if the input
+is a word, <CODE>false</CODE> if the input is a list.  (This is the opposite
+of the output from <CODE>listp</CODE>.)
+
+<P><CODE>Emptyp</CODE> is also a predicate with one input.  The input can be any
+datum. The output from <CODE>emptyp</CODE> is <CODE>true</CODE> if the input is
+either the empty word or the empty list; if the input is anything
+else, the output is <CODE>false</CODE>.
+
+<P>You'll have noticed by now that predicates tend to have names ending
+in the letter <CODE>p</CODE>.  This is not quite a universal rule, but almost.
+It's a good idea to follow the same convention in naming your
+own predicates.<SUP>*</SUP>
+
+<P><SMALL><BLOCKQUOTE><SMALL><SUP>*</SUP>Many versions of Logo use a question mark at the end
+of names of predicates, instead of a <CODE>p</CODE>.  For example, you may see <CODE>
+list?</CODE> instead of <CODE>listp</CODE>.  Berkeley Logo accepts either form, but I
+prefer the <CODE>p</CODE> version.</SMALL></BLOCKQUOTE></SMALL><P>
+
+<P>As I'm describing primitive predicates, you might want to try them
+out on the computer.  You can do experiments like this:
+
+<P><PRE>? <U>print wordp &quot;hello</U>
+true
+? <U>print wordp [hello]</U>
+false
+? <U>print emptyp []</U>
+true
+? <U>print emptyp 0</U>
+false
+</PRE>
+
+<P>Of course, most of the time you won't actually want to print
+the output from a predicate.  You'll see in a few moments
+how we can use a predicate to control the instructions carried out
+in a procedure.
+
+<P>But first here are a few more primitive predicates.  <CODE>Numberp</CODE> takes one
+input, which can be any datum.  The output from <CODE>numberp</CODE> is <CODE>
+true</CODE> if the input is a number, <CODE>false</CODE> otherwise.
+
+<P><CODE>Equalp</CODE> takes two inputs, each of which can be any datum.  The output
+from <CODE>equalp</CODE> is <CODE>true</CODE> if the two inputs are identical or if they're
+both numbers and they're numerically equal.  That is, 3 and 3.0 are
+numerically equal even though they're not identical words.  A list is
+never equal to a word.
+
+<P><PRE>? <U>print equalp 3 3.0</U>
+true
+? <U>print equalp &quot;hello [hello]</U>
+false
+? <U>print equalp &quot;hello first [hello]</U>
+true
+? <U>print equalp &quot; []</U>
+false
+? <U>print equalp [] butfirst [hello]</U>
+true
+</PRE>
+
+<P>
+
+<P>The equal sign (<CODE>=</CODE>) can
+be used as an <EM>infix</EM> equivalent
+of <CODE>equalp</CODE>:
+
+<P><PRE>? <U>print &quot;hello = first [hello]</U>
+true
+? <U>print 2 = 3</U>
+false
+</PRE>
+
+<P>As I mentioned in Chapter 2, if you use infix operations
+you have to be careful about what is grouped with what.  It varies
+between versions of Logo.  Here is an example I tried in Berkeley Logo:
+
+<P><PRE>? <U>print first [hello] = &quot;hello</U>
+f
+</PRE>
+
+<P>Among current commercial implementations, Object Logo and
+Microworlds give the same answer <CODE>f</CODE>.  But here is the <EM>same</EM>
+example in Logowriter:
+
+<P><PRE>? <U>print first [hello] = &quot;hello</U>
+true
+</PRE>
+
+<P>You can avoid confusion by using parentheses.  The following
+instructions work reliably in any Logo:
+
+<P><PRE>? <U>print (first [hello]) = &quot;hello</U>
+true
+? <U>print first ([hello] = &quot;hello)</U>
+f
+</PRE>
+
+<P><CODE>Memberp</CODE> is a predicate with two inputs.  If the second input is a
+list, then the first can be any datum.  If the second input is a word, then
+the first must be a one-character word.  The output from <CODE>memberp</CODE>
+is true if the first input is a member of the second input.
+
+<P><PRE>? <U>print memberp &quot;rain [the rain in Spain]</U>
+true
+? <U>print memberp [the rain] [the rain in Spain]</U>
+false
+? <U>print memberp [the rain] [[the rain] in Spain]</U>
+true
+? <U>print memberp &quot;e &quot;please</U>
+true
+? <U>print memberp &quot;e &quot;plain</U>
+false
+</PRE>
+
+<P><CODE>Lessp</CODE> and <CODE>greaterp</CODE> are predicates that take two inputs.
+Both inputs must be numbers.  The output from <CODE>lessp</CODE> is <CODE>true</CODE> if
+the first input is numerically less than the second; the output from <CODE>
+greaterp</CODE> is true if the first is greater than the second.  Otherwise the
+output is <CODE>false</CODE>.  (In particular, both <CODE>lessp</CODE> and <CODE>greaterp</CODE>
+output <CODE>false</CODE> if the two inputs are equal.) The infix forms for <CODE>
+lessp</CODE> (<CODE>&lt;</CODE>) and <CODE>greaterp</CODE> (<CODE>&gt;</CODE>) are also allowed.
+
+<P><H2>Defining Your Own Predicates</H2>
+
+<P>Here are two examples of how you can create new predicates:
+
+<P><PRE>to vowelp :letter
+output memberp :letter [a e i o u]
+end
+
+? <U>print vowelp &quot;e</U>
+true
+? <U>print vowelp &quot;g</U>
+false
+
+to oddp :number
+output equalp (remainder :number 2) 1
+end
+
+? <U>print oddp 5</U>
+true
+? <U>print oddp 8</U>
+false
+</PRE>
+
+<P><H2>Conditional Evaluation</H2>
+
+<P> The main use of predicates is to
+compute inputs to the primitive procedures <CODE>if</CODE> and <CODE>ifelse</CODE>.
+We'll get to <CODE>ifelse</CODE> in a while, but first we'll explore <CODE>if</CODE>.
+
+<P>
+<CODE>If</CODE> is a command with two inputs.  The first input must
+be either the word <CODE>true</CODE> or the word <CODE>false</CODE>.  The second input must
+be a list containing Logo instructions.  If the first input is <CODE>true</CODE>,
+the effect of <CODE>if</CODE> is to evaluate the instructions in the second input.
+If the first input is <CODE>false</CODE>, <CODE>if</CODE> has no effect.
+
+<P><PRE>? <U>if equalp 2 1+1 [print &quot;Yup.]</U>
+Yup.
+? <U>if equalp 3 2 [print &quot;Nope.]</U>
+?
+</PRE>
+
+<P>Here is an example of how <CODE>if</CODE> can be used in a procedure.
+This is an extension of the <CODE>converse</CODE> example in Chapter 3:
+
+<P><PRE>to talk
+local &quot;name
+print [Please type your full name.]
+make &quot;name readlist
+print sentence [Your first name is] first :name
+if (count :name) &gt; 2 ~
+   [print sentence [Your middle name is] first bf :name]
+print sentence [Your last name is] last :name
+end
+
+? <U>talk</U>
+Please type your full name.
+<U>George Washington</U>
+Your first name is George
+Your last name is Washington
+? <U>talk</U>
+Please type your full name.
+<U>John Paul Jones</U>
+Your first name is John
+Your middle name is Paul
+Your last name is Jones
+</PRE>
+
+<P><CODE>Talk</CODE> asks you to type your name and reads what you type
+into a list, which is remembered in the variable named <CODE>
+name</CODE>.  Your first and last names are printed as in the earlier
+version.  If the list <CODE>:name</CODE> contains more than two members,
+however, <CODE>talk</CODE> also prints the second member as your middle
+name.  If <CODE>:name</CODE> contains only two members, <CODE>talk</CODE> assumes
+that you don't have a middle name.
+
+<P>&raquo;Write a procedure of your own that asks a question and uses <CODE>if</CODE> to
+find out something about the response.
+
+<P>You can use <CODE>if</CODE> to help in writing more interesting predicates.
+
+<P><PRE>to about.computersp :sentence
+if memberp &quot;computer :sentence [output &quot;true]
+if memberp &quot;computers :sentence [output &quot;true]
+if memberp &quot;programming :sentence [output &quot;true]
+output &quot;false
+end
+
+? <U>print about.computersp [This book is about programming]</U>
+true
+? <U>print about.computersp [I like ice cream]</U>
+false
+?
+</PRE>
+
+<P>This procedure illustrates something I didn't explain before about <CODE>
+output</CODE>: An <CODE>output</CODE> command finishes the evaluation of the
+procedure in which it occurs.  For example, in <CODE>about.computersp</CODE>,
+if the input sentence contains the word <CODE>computer</CODE>, the first <CODE>
+if</CODE> evaluates the <CODE>output</CODE> instruction that is its second input.
+The procedure immediately outputs the word <CODE>true</CODE>.  The remaining
+instructions are not evaluated at all.
+
+<P>&raquo;Write <CODE>past.tensep</CODE>, which takes a word as input and
+outputs <CODE>true</CODE> if the word ends in <CODE>ed</CODE> or if it's one of a list of
+exceptions, like <CODE>saw</CODE> and <CODE>went</CODE>.
+
+<P>&raquo;Write <CODE>integerp</CODE>, which takes any Logo datum as input and
+outputs <CODE>true</CODE> if and only if the datum is an integer (a number without a
+fraction part).  Hint: a number with a fraction part will contain a decimal
+point.
+
+<P><H2>Choosing Between Alternatives</H2>
+
+<P><CODE>If</CODE> gives the choice between carrying out some instructions and doing
+nothing at all.  More generally, we may want to carry out either of <EM>
+two</EM> sets of instructions, depending on the output from a predicate.
+The primitive procedure <CODE>ifelse</CODE> meets this need.<SUP>*</SUP>  <CODE>Ifelse</CODE> is
+an unusual primitive because it can be used either as a command or as an
+operation.  We'll start with examples in which <CODE>ifelse</CODE> is used as a
+command.
+
+<P><SMALL><BLOCKQUOTE><SMALL><SUP>*</SUP>In some
+versions of Logo, the name <CODE>if</CODE> is used both for the two-input command
+discussed earlier and for the three-input one presented here.</SMALL></BLOCKQUOTE></SMALL><P><CODE>Ifelse</CODE> requires three inputs.  The first input must be either the word
+<CODE>true</CODE> or the word <CODE>false</CODE>.  The second and third inputs must be
+lists containing Logo instructions.  If the first input is <CODE>true</CODE>, the
+effect of <CODE>if</CODE> is to evaluate the instructions in the second input.  If
+the first input is <CODE>false</CODE>, the effect is to evaluate the instructions
+in the third input.
+
+<P><PRE>? <U>ifelse 4 = 2+2 [print &quot;Yup.] [print &quot;Nope.]</U>
+Yup.
+? <U>ifelse 4 = 3+5 [print &quot;Yup.] [print &quot;Nope.]</U>
+Nope.
+?
+</PRE>
+
+<P>
+Here is an example of a procedure using <CODE>ifelse</CODE>:
+
+<P><PRE>to groupie
+local &quot;name
+print [Hi, who are you?]
+make &quot;name readlist
+ifelse :name = [Ray Davies] ~
+     [print [May I have your autograph?]] ~
+     [print sentence &quot;Hi, first :name]
+end
+
+? <U>groupie</U>
+Hi, who are you?
+<U>Frank Sinatra</U>
+Hi, Frank
+? <U>groupie</U>
+Hi, who are you?
+<U>Ray Davies</U>
+May I have your autograph?
+</PRE>
+
+<P>&raquo;Write an operation <CODE>color</CODE> that takes as input a word
+representing a card, such as <CODE>10h</CODE> for the ten of hearts.  Its output
+should be the word <CODE>red</CODE> if the card is a heart or a diamond, or <CODE>
+black</CODE> if it's a spade or a club.
+
+<P>&raquo;Write a conversational program that asks the user's name and figures
+out how to address him or her.  For example:
+
+<P><PRE>? <U>converse</U>
+Hi, what's your name?
+<U>Chris White</U>
+Pleased to meet you, Chris.
+
+? <U>converse</U>
+Hi, what's your name?
+<U>Ms. Grace Slick</U>
+Pleased to meet you, Ms. Slick.
+
+? <U>converse</U>
+Hi, what's your name?
+<U>J. Paul Getty</U>
+Pleased to meet you, Paul.
+
+? <U>converse</U>
+Hi, what's your name?
+<U>Sigmund Freud, M.D.</U>
+Pleased to meet you, Dr. Freud.
+
+? <U>converse</U>
+Hi, what's your name?
+<U>Mr. Lon Chaney, Jr.</U>
+Pleased to meet you, Mr. Chaney.
+</PRE>
+
+<P>What should the program say if it meets Queen Elizabeth II?
+
+
+<P><H2>Conditional Evaluation Another Way</H2>
+
+<P>The use of <CODE>ifelse</CODE> in the <CODE>groupie</CODE> example above makes for
+a rather long instruction line.  If you wanted to do several instructions
+in each case, rather than just one <CODE>print</CODE>, the <CODE>if</CODE> line would become
+impossible to read.  Logo provides another mechanism that is equivalent
+to the <CODE>ifelse</CODE> command but may be easier to read.
+
+<P><CODE>Test</CODE> is a command that takes one input.  The input must be
+either the word <CODE>true</CODE> or the word <CODE>false</CODE>.  The effect of
+<CODE>test</CODE> is just to remember what its input was in a special place.
+You can think of this place as a variable without a name.  This
+special variable is automatically local to the procedure from which
+<CODE>test</CODE> is invoked.
+
+<P><CODE>Iftrue</CODE> (abbreviation <CODE>ift</CODE>) is a command with one
+input.  The input must be a list of Logo instructions.  The effect of
+<CODE>iftrue</CODE> is to evaluate the instructions in its input only if the
+unnamed variable set by the most recent <CODE>test</CODE> command in the same
+procedure is <CODE>true</CODE>.  It is an error to use <CODE>iftrue</CODE> without
+first using <CODE>test</CODE>.
+
+<P><CODE>Iffalse</CODE> (abbreviation <CODE>iff</CODE>) is a command with one input, which
+must be an instruction list.  The effect of <CODE>iffalse</CODE> is to evaluate
+the instructions only if the remembered result of the most recent <CODE>test</CODE>
+command is <CODE>false</CODE>.
+
+<P><CODE>Iftrue</CODE> and <CODE>iffalse</CODE> can be invoked as many times as you like after
+a <CODE>test</CODE>.  This allows you to break up a long sequence of conditionally evaluated
+instructions into several instruction lines:
+
+<P><PRE>to better.groupie
+local &quot;name
+print [Hi, who are you?]
+make &quot;name readlist
+test equalp :name [Ray Davies]
+iftrue [print [Wow, can I have your autograph?]]
+iftrue [print [And can I borrow a thousand dollars?]]
+iffalse [print sentence [Oh, hello,] first :name]
+end
+</PRE>
+
+<P><H2>About Those Brackets</H2>
+
+<P>I hope that the problem I'm about to mention won't even have occurred
+to you because you are so familiar with the idea of evaluation that
+you understood right away.  But you'll probably have to explain it
+to someone else, so I thought I'd bring it up here:
+
+<P>
+
+Some people get confused about why the second
+input to <CODE>if</CODE> (and the second and third inputs to <CODE>ifelse</CODE>)
+is surrounded by brackets but the first isn't.  That
+is, they wonder, why don't we say
+
+<P><PRE>if [equalp 2 3] [print &quot;really??]          ; (wrong!)
+</PRE>
+
+<P>They have this problem because someone lazily told them
+to put brackets around the conditionally evaluated instructions without
+ever explaining about brackets and quotation.
+
+<P>I trust <EM>you</EM> aren't confused that way.  You understand that, as usual,
+Logo evaluates the inputs to a procedure before invoking the procedure.  The
+first input to <CODE>if</CODE> has to be either the word <CODE>true</CODE> or the word
+<CODE>false</CODE>.  <EM>Before</EM> invoking <CODE>if</CODE>, Logo has to evaluate an
+expression like <CODE>equalp 2 3</CODE> to compute the input.  (In this case, the
+result output by <CODE>equalp</CODE> will be <CODE>false</CODE>.)  But if the <CODE>print</CODE>
+instruction weren't quoted, Logo would evaluate it, too, <EM>before</EM>
+invoking <CODE>if</CODE>.  That's not what we want.  We want the instruction list
+<EM>itself</EM> to be the second input, so that <CODE>if</CODE> can decide whether
+or not to carry out the instructions in the list.  So, as usual, we use
+brackets to tell Logo to quote the list.
+
+<P><CENTER><TABLE rules="groups" frame="void" border="2">
+<THEAD>
+<TR><TH>actual argument expression<TH>--&gt;<TH>actual argument value
+<TBODY>
+<TR><TD><CODE>equalp 2 3</CODE><TD>--&gt;<TD><CODE>false</CODE>
+<TR><TD><CODE>[print &quot;really??]</CODE><TD>--&gt;<TD><CODE>[print &quot;really??]</CODE>
+</TABLE></CENTER>
+
+<P><H2>Logical Connectives</H2>
+
+<P>Sometimes the condition under which you want to evaluate an instruction
+is complicated.  You want to do it if <EM>both</EM> this <EM>and</EM> that
+are true, or if <EM>either</EM> this <EM>or</EM> that is true.  Logo provides
+operations for this purpose.
+
+<P><CODE>And</CODE> is a predicate with two inputs.  Each input must be either the
+word <CODE>true</CODE> or the word <CODE>false</CODE>.  The output from <CODE>and</CODE> is
+<CODE>true</CODE> if both inputs are <CODE>true</CODE>; the output is <CODE>false</CODE> if
+either input is <CODE>false</CODE>.  (<CODE>And</CODE> can take more than two inputs if
+the entire expression is enclosed in parentheses.  In that case the output
+from <CODE>and</CODE> will be <CODE>true</CODE> only if all of its inputs are <CODE>true</CODE>.)
+
+<P><CODE>Or</CODE> is a predicate with two inputs.  Each input must be either the
+word <CODE>true</CODE> or the word <CODE>false</CODE>.  The output from <CODE>or</CODE> is
+<CODE>true</CODE> if either input is <CODE>true</CODE> (or both inputs are).  The
+output is <CODE>false</CODE> if both inputs are <CODE>false</CODE>.  (Extra-input
+<CODE>or</CODE> outputs <CODE>true</CODE> if any of its inputs are <CODE>true</CODE>, <CODE>
+false</CODE> if all inputs are <CODE>false</CODE>.)
+
+<P><CODE>Not</CODE> is a predicate with one input.  The input must be either the
+word <CODE>true</CODE> or the word <CODE>false</CODE>.  The output from <CODE>not</CODE> is
+the opposite of its input: <CODE>true</CODE> if the input is <CODE>false</CODE>, or
+<CODE>false</CODE> if the input is <CODE>true</CODE>.
+
+<P>
+
+These three procedures are called <EM>logical connectives</EM> because
+they connect logical expressions together into bigger ones.  (A <EM>
+logical</EM> expression is one whose value is <CODE>true</CODE> or <CODE>
+false</CODE>.) They can be useful in defining new predicates:
+
+<P><PRE>to fullp :datum
+output not emptyp :datum
+end
+
+to realwordp :datum
+output and wordp :datum not numberp :datum
+end
+
+to digitp :datum
+output and numberp :datum equalp count :datum 1
+end
+</PRE>
+
+<P><H2><CODE>Ifelse</CODE> as an Operation</H2>
+
+<P>So far, we have applied the idea of conditional evaluation only to
+complete instructions.  It is also possible to choose between two
+expressions to evaluate, by using <CODE>ifelse</CODE> as an
+operation.
+
+<P>When used as an operation, <CODE>ifelse</CODE> requires three inputs.  The first input
+must be either the word <CODE>true</CODE> or the word <CODE>false</CODE>.  The second and third
+inputs must be lists containing Logo expressions.  The output from
+<CODE>ifelse</CODE> is the result of evaluating the second input, if the first input
+is <CODE>true</CODE>, or the result of evaluating the third input, if the first
+input is <CODE>false</CODE>.
+
+<P><PRE>? <U>print sentence &quot;It's ifelse 2=3 [&quot;correct] [&quot;incorrect]</U>
+It's incorrect
+? <U>print ifelse emptyp [] [sum 2 3] [product 6 7]</U>
+5
+</PRE>
+
+<P>Here is one of the classic examples of a procedure in which <CODE>ifelse</CODE> is
+used as an operation.  This procedure is an operation that takes
+a number as its input; it outputs the <EM>absolute value</EM> of the
+number:
+
+<P><PRE>to abs :number
+output ifelse :number&lt;0 [-:number] [:number]
+end
+</PRE>
+
+<P><H2>Expression Lists and Plumbing Diagrams</H2>
+
+<P><CODE>If</CODE> and <CODE>ifelse</CODE> require <EM>instruction lists</EM> or <EM>
+expression lists</EM> as inputs.  This requirement is part of their semantics,
+not part of the syntax of an instruction.  Just as the arithmetic operators
+require numbers as inputs (semantics), but those numeric values can be
+provided either as explicit numbers in the instruction or as the result of
+an arbitrarily complicated subexpression (syntax), the procedures that
+require instruction or expression lists as input don't interpret those
+inputs until after Logo has set up the plumbing for the instructions that
+invoke them.
+
+<P>What does that mean?  Consider the instruction
+
+<P><PRE>ifelse &quot;false [&quot;stupid &quot;list] [print 23]
+</PRE>
+
+<P>Even though the second input to <CODE>ifelse</CODE>--that is, the first
+of the two literal lists--makes no sense as an instruction list, this
+instruction will work correctly without printing an error message.  The Logo
+interpreter knows that <CODE>ifelse</CODE> accepts three inputs, and it sees that
+the three input expressions provided are a literal (quoted) word and two
+literal lists.  It sets up the plumbing without paying any attention to the
+semantics of <CODE>ifelse</CODE>; in particular, Logo doesn't care whether the
+given inputs are meaningful for use with <CODE>ifelse</CODE>.  Then, once <CODE>
+ifelse</CODE> starts running, it examines its first input value.  Since that input
+is the word <CODE>false</CODE>, the <CODE>ifelse</CODE> procedure ignores its second input
+completely and executes the instruction in its third input.
+
+<P>The use of quotation marks and square brackets to indicate literal inputs is
+part of the plumbing syntax, not part of the procedure semantics.  Don't say,
+&quot;<CODE>Ifelse</CODE> requires one predicate input and two inputs in square
+brackets.&quot;  The instruction
+
+<P><PRE>ifelse last [true false] list &quot;&quot;stupid &quot;&quot;list list bf &quot;sprint 23
+</PRE>
+
+<P>has a very different plumbing diagram (syntax) from that of the
+earlier example, but provides exactly the same input values to <CODE>ifelse</CODE>.
+
+<P>Consider these two instructions:
+
+<P><CENTER><IMG SRC="https://people.eecs.berkeley.edu/~bh/v1ch4/printfirst.gif" ALT="figure: printfirst"></CENTER>
+
+<P>Since the effect of <CODE>print</CODE> is easy to observe, it's not hard
+to see the relationship among the instructions, the plumbing diagrams, and
+the effects when these instructions are run.  Why are brackets used around
+the <CODE>first</CODE> expression in one case but not in the other?  Because in one
+case the expression is how we tell Logo to set up the plumbing diagram,
+while in the second case we are giving <CODE>print</CODE> as input a literal list
+that just happens to look like an expression.  When the context is something
+like <CODE>ifelse</CODE> instead of <CODE>print</CODE>, the syntactic situation is really
+quite similar, but may be harder to see.  Consider this instruction:
+
+<P><PRE>print ifelse emptyp :a [emptyp :b] [emptyp :c]
+</PRE>
+
+<P>Why do we put brackets around two <CODE>emptyp</CODE> expressions but not
+around another similar-looking one?  &raquo; Draw a plumbing diagram
+for this instruction, paying no attention to your mental model of the
+meaning of the <CODE>ifelse</CODE> procedure, treating it as if it were the
+nonsense procedure <CODE>zot3</CODE>.  You will see that the first input to <CODE>
+ifelse</CODE> is an expression whose value will be the word <CODE>true</CODE> or the word
+<CODE>false</CODE>, because Logo will carry out that first <CODE>emptyp</CODE> computation
+before invoking <CODE>ifelse</CODE>.  The remaining two inputs, however, are
+literal lists that happen to contain the word <CODE>emptyp</CODE> but do not
+involve an invocation of <CODE>emptyp</CODE> in the plumbing diagram.  Once <CODE>
+ifelse</CODE> is actually invoked, precisely one of those two list inputs will be
+interpreted as a Logo expression, for which a <EM>new</EM> plumbing diagram
+is (in effect) drawn by Logo.  The other input list is ignored.
+
+<P><H2>Stopping a Procedure</H2>
+
+<P>I'd like to examine more closely one of the examples from the first
+chapter:
+
+<P><PRE>to music.quiz
+print [Who is the greatest musician of all time?]
+if equalp readlist [John Lennon] [print [That's right!] stop]
+print [No, silly, it's John Lennon.]
+end
+</PRE>
+
+<P>You now know about almost all of the primitive procedures
+used in this example.  The only one we haven't discussed is the <CODE>stop</CODE>
+command in the second instruction line.
+
+<P><CODE>Stop</CODE> is a command that takes no inputs.  It is only allowed inside
+a procedure; you can't type <CODE>stop</CODE> to a top-level prompt.  The effect
+of <CODE>stop</CODE> is to finish the evaluation of the procedure in which it is
+used.  Later instructions in the same procedure are skipped.
+
+<P>Notice that <CODE>stop</CODE> does not stop <EM>all</EM> active procedures.  If procedure
+A invokes procedure B, and there is a <CODE>stop</CODE> command in procedure B,
+then procedure A continues after the point where it invoked B.
+
+<P>Recall that the <CODE>output</CODE> command also stops the procedure that invokes
+it.  The difference is that if you're writing an operation, which
+should have an output, you use <CODE>output</CODE>; if you're writing a command,
+which doesn't have an output, you use <CODE>stop</CODE>.
+
+<P>In <CODE>music.quiz</CODE>, the effect of the <CODE>stop</CODE> is that if you get the right
+answer, the final <CODE>print</CODE> instruction isn't evaluated.  The same effect
+could have been written this way:
+
+<P><PRE>ifelse equalp readlist [John Lennon] ~
+    [print [That's right!]] ~
+    [print [No, silly, it's John Lennon.]]
+</PRE>
+
+<P>The alternative form uses the three-input <CODE>ifelse</CODE> command.  One
+advantage of using <CODE>stop</CODE> is precisely that it allows the use of
+shorter lines.  But in this example, where there is only one
+instruction after the <CODE>if</CODE>, it doesn't matter much.  <CODE>Stop</CODE> is
+really useful when you want to stop only in an unusual situation and
+otherwise you have a lot of work still to do:
+
+<P><PRE>to quadratic :a :b :c
+local &quot;discriminant
+make &quot;discriminant (:b * :b)-(4 * :a * :c)
+<U>if :discriminant &lt; 0 [print [No solution.] stop]</U>
+make &quot;discriminant sqrt :discriminant
+local &quot;x1
+local &quot;x2
+make &quot;x1 (-:b + :discriminant)/(2 * :a)
+make &quot;x2 (-:b - :discriminant)/(2 * :a)
+print (sentence [x =] :x1 [or] :x2)
+end
+</PRE>
+
+<P>This procedure applies the quadratic formula to solve the
+equation
+
+<P><CENTER><EM>ax</EM>&#178;+<EM>bx</EM>+<EM>c</EM>=0</CENTER>
+
+<P>The only interesting thing about this example for our present purpose
+is the fact that sometimes there is no solution.  In that case the
+procedure <CODE>stop</CODE>s as soon as it finds out.
+
+<P>Don't forget that you need <CODE>stop</CODE> only if you want to stop a
+procedure before its last instruction line.  A common mistake made by
+beginners who've just learned about <CODE>stop</CODE> is to use it in every
+procedure.  If you look back at the examples so far you'll see that
+many procedures get along fine without invoking <CODE>stop</CODE>.
+
+<P><H2>Improving the Quiz Program</H2>
+
+<P>When I first introduced the <CODE>music.quiz</CODE> example in Chapter 1, we
+hadn't discussed things like user procedures with inputs.  We are now in a
+position to generalize the quiz program:
+
+<P><PRE>to qa :question :answer
+print :question
+if equalp readlist :answer [print [That's right!] stop]
+print sentence [Sorry, it's] :answer
+end
+
+to quiz
+qa [Who is the best musician of all time?] [John Lennon]
+qa [Who wrote &quot;Compulsory Miseducation&quot;?] [Paul Goodman]
+qa [What color was George Washington's white horse?] [white]
+qa [how much is 2+2?] [5]
+end
+</PRE>
+
+Procedure <CODE>qa</CODE> is our old friend <CODE>music.quiz</CODE>, with variable
+inputs instead of a fixed question and answer.  <CODE>Quiz</CODE> uses <CODE>qa</CODE> several
+times to ask different questions.
+
+<P>&raquo;Here are a couple of suggestions for further improvements you should
+be able to make to <CODE>quiz</CODE> and <CODE>qa</CODE>:
+
+<P>1.  <CODE>Qa</CODE> is very fussy about getting one particular answer to a
+question. If you answer <CODE>Lennon</CODE> instead of <CODE>John Lennon</CODE>,
+it'll tell you you're wrong.  There are a couple of ways you might fix
+this.  One is to look for a single-word answer <EM>anywhere within</EM>
+what the user types.  So if <CODE>:answer</CODE> is the word <CODE>Lennon</CODE>,
+the program will accept &quot;<CODE>Lennon</CODE>,&quot; &quot;<CODE>John Lennon</CODE>,&quot; or &quot;<CODE>the
+Lennon Sisters</CODE>.&quot;  The second approach would be for <CODE>qa</CODE> to take a
+<EM>list</EM> of possible answers as its second input:
+
+<P><PRE>qa [Who is the best musician of all time?] ~
+   [[John Lennon] [Lennon] [the Beatles]]
+</PRE>
+
+<P><CODE>Qa</CODE> then has to use a different predicate, to see if what
+the user types is any of the answers in the list.
+
+<P>2.  By giving <CODE>quiz</CODE> a local variable named <CODE>score</CODE>, you could
+have <CODE>quiz</CODE> and <CODE>qa</CODE> cooperate to keep track of how many
+questions the user gets right.  At the end the score could be printed.
+(This is an opportunity to think about the stylistic virtues and vices
+of letting a subprocedure modify a variable that belongs to its
+superprocedure.  If you say
+
+<P><PRE>make &quot;score :score+1
+</PRE>
+
+<P>inside <CODE>qa</CODE>, doesn't that make <CODE>quiz</CODE> somewhat mysterious
+to read?  For an alternative, read the next section.)
+
+<P><H2>Reporting Success to a Superprocedure</H2>
+
+<P>Suppose we want the quiz program to give the user three tries before
+revealing the right answer.  There are several ways this could be
+programmed.  Here is a way that uses the tools you already know about.
+
+<P>The general idea is that the procedure that asks the question is
+written as an <EM>operation,</EM> not as a command.  To be exact, it's a
+predicate; it outputs <CODE>true</CODE> if the user gets the right answer.
+This asking procedure, <CODE>ask.once</CODE>, is invoked as a subprocedure of
+<CODE>ask.thrice</CODE>, which is in charge of allowing three tries.  <CODE>
+ask.thrice</CODE> invokes <CODE>ask.once</CODE> up to three times, but stops if
+<CODE>ask.once</CODE> reports success.
+
+<P><PRE>to ask.thrice :question :answer
+repeat 3 [if ask.once :question :answer [stop]]
+print sentence [The answer is] :answer
+end
+
+to ask.once :question :answer
+print :question
+if equalp readlist :answer [print [Right!] output &quot;true]
+print [Sorry, that's wrong.]
+output &quot;false
+end
+</PRE>
+
+<P>
+You've seen <CODE>repeat</CODE> in the first chapter, but you haven't been formally
+introduced.  <CODE>Repeat</CODE> is a command with two inputs.  The first input
+must be a non-negative whole number.  The second input must be a list
+of Logo instructions.  The effect of <CODE>repeat</CODE> is to evaluate its second
+input, the instruction list, the number of times given as the first
+input.
+
+<P>The programming style used in this example is a little controversial.
+In general, it's considered a good idea not to mix effect and output
+in one procedure.  But in this example, <CODE>ask.once</CODE> has an effect (it
+prints the question, reads an answer, and comments on its correctness)
+and also an output (<CODE>true</CODE> or <CODE>false</CODE>).
+
+<P>I think the general rule I've just cited is a good rule, but there
+are exceptions to it.  Using an output of <CODE>true</CODE> or <CODE>false</CODE> to report
+the success or failure of some process is one of the situations that
+I consider acceptable style.  The real point of the rule, I think,
+is to separate <EM>calculating</EM> something from <EM>
+printing</EM> it.  For example, it's a mistake to write procedures like this
+one:
+
+<P><PRE>to <A NAME="prsecond">prsecond :datum
+print first butfirst :datum
+end
+</PRE>
+
+<P>
+A more powerful technique is to write the <CODE>second</CODE> operation
+from Chapter 2; instead of
+
+<P><PRE>prsecond [something or other]
+</PRE>
+
+<P>you can then say
+
+<P><PRE>print second [something or other]
+</PRE>
+
+<P>It may not be obvious from this example why I call <CODE>second</CODE>
+more powerful than <CODE>prsecond</CODE>.  But remember that an operation can be
+combined with other operations, as in the plumbing diagrams we used
+earlier.  For example, the operation <CODE>second</CODE> can extract the word <CODE>
+or</CODE> from the list as shown here.  But you can <EM>also</EM> use it as part of
+a more complex instruction to extract the letter <CODE>o</CODE>:
+
+<P><PRE>print first second [something or other]
+</PRE>
+
+<P>If you'd written the command <CODE>prsecond</CODE> to solve the
+first problem, you'd have to start all over again to solve this new
+one.  (Of course, both of these examples must seem pretty silly; why
+bother extracting a word or a letter from this list?  But I'm trying
+to use examples that are simple enough not to obscure this issue with
+the kinds of complications we'll see in more interesting programs.)
+
+<P>&raquo;If you made the improvements to <CODE>quiz</CODE> and <CODE>qa</CODE> that I
+suggested earlier, you might like to see if they can fit easily with a new
+version of <CODE>quiz</CODE> using <CODE>ask.thrice</CODE>.
+
+<P><A HREF="../v1-toc2.html">(back to Table of Contents)</A>
+<P><A HREF="../v1ch3/v1ch3.html"><STRONG>BACK</STRONG></A>
+chapter thread <A HREF="../v1ch5/v1ch5.html"><STRONG>NEXT</STRONG></A>
+
+<P>
+<ADDRESS>
+<A HREF="../index.html">Brian Harvey</A>, 
+<CODE>bh@cs.berkeley.edu</CODE>
+</ADDRESS>
+</BODY>
+</HTML>