about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/ssch6/true.html
diff options
context:
space:
mode:
Diffstat (limited to 'js/games/nluqo.github.io/~bh/ssch6/true.html')
-rw-r--r--js/games/nluqo.github.io/~bh/ssch6/true.html892
1 files changed, 892 insertions, 0 deletions
diff --git a/js/games/nluqo.github.io/~bh/ssch6/true.html b/js/games/nluqo.github.io/~bh/ssch6/true.html
new file mode 100644
index 0000000..66a31da
--- /dev/null
+++ b/js/games/nluqo.github.io/~bh/ssch6/true.html
@@ -0,0 +1,892 @@
+<P>
+<A NAME="dumdee"></A>
+<P><CENTER><IMG SRC="../ss-pics/tweedle.jpg" ALT="figure: tweedle"></CENTER><P><CENTER>&quot;Contrariwise,&quot; continued Tweedledee, &quot;if it was so,
+it might be; and if it were so, it would be; but as it isn't, it ain't.
+That's logic.&quot;
+</CENTER><P>
+
+<HTML>
+<HEAD>
+<TITLE>Simply Scheme: Introducing Computer Science ch 6: True and False</TITLE>
+</HEAD>
+<BODY>
+<HR>
+<CITE>Simply Scheme:</CITE>
+<CITE>Introducing Computer Science</CITE> 2/e Copyright (C) 1999 MIT
+<H2>Chapter 6</H2>
+<H1>True and False</H1>
+
+<TABLE width="100%"><TR><TD>
+<IMG SRC="../simply.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"><CITE><A HREF="http://ccrma.stanford.edu/~matt">Matthew
+Wright</A><BR>University of California, Santa Barbara</CITE>
+<TR><TD align="right"><BR>
+<TR><TD align="right"><A HREF="../pdf/ssch06.pdf">Download PDF version</A>
+<TR><TD align="right"><A HREF="../ss-toc2.html">Back to Table of Contents</A>
+<TR><TD align="right"><A HREF="../ssch5/words.html"><STRONG>BACK</STRONG></A>
+chapter thread <A HREF="../ssch7/variables.html"><STRONG>NEXT</STRONG></A>
+<TR><TD align="right"><A HREF="http://mitpress.mit.edu/0262082810">MIT
+Press web page for <CITE>Simply Scheme</CITE></A>
+</TABLE></TABLE>
+
+<HR>
+
+
+<P>We still need one more thing before we can write more interesting programs: 
+the ability to make decisions.  Scheme has a way to say &quot;if this is true,
+then do this thing, otherwise do something else.&quot;
+
+<P>Here's a procedure that greets a person:
+
+<P><PRE>(define (<A NAME="g63"></A>greet name)
+  (if (equal? (first name) 'professor)
+      (se '(i hope i am not bothering you) 'professor (last name))
+      (se '(good to see you) (first name))))
+
+&gt; (greet '(matt wright))
+(GOOD TO SEE YOU MATT)
+
+&gt; (greet '(professor harold abelson))
+(I HOPE I AM NOT BOTHERING YOU PROFESSOR ABELSON)
+</PRE>
+
+<P>The program greets a person by checking to see if that person is a
+professor.  If so, it says, &quot;I hope I am not bothering you&quot; and then the
+professor's name.  But if it's a regular person, the program just says,
+&quot;Good to see you,&quot; and then the person's first name.
+
+<P><CODE>If</CODE> takes three arguments.  The first has to be either true or
+false.
+<A NAME="spif"></A>
+<A NAME="g64"></A>
+(We'll talk in a moment about exactly what true and false look like to
+Scheme.)  In the above example, the first word of the person's name might or
+might not be equal to the word &quot;Professor.&quot; The second and third arguments
+are expressions; one or the other of them is evaluated depending on the
+first argument.  The value of the entire <CODE>if</CODE> expression is the value of
+either the second or the third argument.
+
+<P>
+You learned in Chapter 2 that Scheme includes a special data type
+called <EM>Booleans</EM> to represent true or false
+values.  There are just two of them: <A NAME="g65"></A><CODE>#t</CODE> for &quot;true&quot; and
+<A NAME="g66"></A><CODE>#f</CODE> for &quot;false.&quot;<A NAME="dumbfalse"></A><A NAME="text1" HREF="true.html#ft1">[1]</A>
+
+<P>We said that the first argument to <CODE>if</CODE> has to be true or false.  Of
+course, it would be silly to say
+
+<P>
+
+<P><PRE>&gt; (if #t (+ 4 5) (* 2 7))
+9
+</PRE>
+
+<P>
+because what's the point of using <CODE>if</CODE> if we already know
+which branch will be followed?  Instead, as in the <CODE>greet</CODE> example, we call
+some procedure whose return value will be either true or false, depending on
+the particular arguments we give it.
+
+<P><H2>Predicates</H2>
+
+<P>A function that returns either <CODE>#t</CODE> or <CODE>#f</CODE> is called a <EM>predicate.</EM><A NAME="text2" HREF="true.html#ft2">[2]</A> You've
+already seen the <A NAME="g69"></A><CODE>equal?</CODE> predicate.  It takes two arguments, which
+can be of any type, and returns <CODE>#t</CODE> if the two arguments are the same
+value, or <CODE>#f</CODE> if they're different.  It's a convention in Scheme that
+the names of predicates end with a question mark, but that's just a
+convention.  Here are some other useful predicates:
+
+<P>
+<PRE>&gt; (member? 'mick '(dave dee dozy beaky mick and tich))
+#T
+&gt; (member? 'mick '(john paul george ringo))
+#F
+&gt; (member? 'e 'truly)
+#F
+</PRE>
+
+<P>
+<PRE>&gt; (member? 'y 'truly)
+#T
+&gt; (= 3 4)
+#F
+&gt; (= 67 67)
+#T
+&gt; (&gt; 98 97)
+#T
+&gt; (before? 'zorn 'coleman)
+#F
+&gt; (before? 'pete 'ringo)
+#T
+&gt; (empty? '(abbey road))
+#F
+&gt; (empty? '())
+#T
+&gt; (empty? 'hi)
+#F
+&gt; (empty? (bf (bf 'hi)))
+#T
+&gt; (empty? &quot;&quot;)
+#T
+</PRE>
+
+<P>
+
+<P><CODE>Member?</CODE> takes two arguments; it checks to see if the first
+<A NAME="memq"></A>
+<A NAME="g70"></A>
+one is a member of the second.  The <A NAME="g71"></A><CODE>=</CODE>, <A NAME="g72"></A><CODE>&gt;</CODE>, <A NAME="g73"></A><CODE>&lt;</CODE>,
+<A NAME="g74"></A><CODE>&gt;=</CODE>, and <A NAME="g75"></A><CODE>&lt;=</CODE> functions take two numbers as arguments and do the
+obvious comparisons.  (By the way, these are exceptions to the convention about
+question marks.)  <CODE>Before?</CODE> is like <CODE>&lt;</CODE>, but it compares two words
+<A NAME="g76"></A>
+alphabetically.  <CODE>Empty?</CODE> checks to see if its argument
+<A NAME="g77"></A>
+is either the empty word or the empty sentence.
+
+<P>
+
+<P>Why do we have both <CODE>equal?</CODE> and <CODE>=</CODE> in Scheme?  The first of these
+works on any kind of Scheme data, while the second is defined only for
+numbers.  You could get away with always using <CODE>equal?</CODE>, but the more
+specific form makes your program more self-explanatory; people reading the
+program know right away that you're comparing numbers.
+
+<P>
+
+<P>There are also several predicates that can be used to test the type of their
+argument:
+
+<P>
+
+<P><PRE>&gt; (<A NAME="g78"></A>number? 'three)
+#F
+&gt; (number? 74)
+#T
+&gt; (<A NAME="g79"></A>boolean? #f)
+#T
+&gt; (boolean? '(the beatles))
+#F
+</PRE>
+
+<P>
+<PRE>&gt; (boolean? 234)
+#F
+&gt; (boolean? #t)
+#T
+&gt; (<A NAME="g80"></A>word? 'flying)
+#T
+&gt; (word? '(dig it))
+#F
+&gt; (word? 87)
+#T
+&gt; (<A NAME="g81"></A>sentence? 'wait)
+#F
+&gt; (sentence? '(what goes on))
+#T
+</PRE>
+
+<P>Of course, we can also define new predicates:
+
+<P>
+
+<P><PRE>(define (vowel? letter)
+  (member? letter 'aeiou))
+
+(define (positive? number)
+  (&gt; number 0))
+</PRE>
+
+<P><H2>Using Predicates</H2>
+
+<P>Here's a procedure that returns the absolute value of a number:
+
+<P>
+
+<P><PRE>(define (<A NAME="g82"></A>abs num)
+  (if (&lt; num 0)
+      (- num)
+      num))
+</PRE>
+
+<P>
+
+<P>(If you call <A NAME="g83"></A><CODE>-</CODE> with just one argument, it returns the
+negative of that argument.)  Scheme actually provides <A NAME="g84"></A><CODE>abs</CODE> as a
+primitive procedure, but we can redefine it.
+
+<P>Do you remember how to play buzz?  You're all sitting around the campfire
+and you go around the circle counting up from one.  Each person says a
+number.  If your number is divisible by seven or if one of its digits is a
+seven, then instead of calling out your number, you say &quot;buzz.&quot;
+
+<P><PRE>(define (<A NAME="g85"></A>buzz num)
+  (if (or (divisible? num 7) (member? 7 num))
+      'buzz
+      num))
+
+(define (<A NAME="g86"></A>divisible? big little)
+  (= (remainder big little) 0))
+</PRE>
+
+<P><CODE>Or</CODE> can take any number of arguments, each of which must be
+true or false.  It returns true if any of its arguments are true, that is, if
+the first argument is true <EM>or</EM> the second argument is true <EM>or</EM>&hellip  (<CODE>Remainder</CODE>, as you know, takes two integers and tells
+you what the remainder is when you divide the first by the second.  If the
+remainder is zero, the first number is divisible by the second.)
+
+<P><CODE>Or</CODE> is one of three functions in Scheme that combine true or false
+values to produce another true or false value.  <CODE>And</CODE> returns true if
+<A NAME="g87"></A> all of its arguments are true, that is, the first <EM>and</EM>
+second <EM>and</EM>&hellip  Finally, there's a function <A NAME="g88"></A><CODE>not</CODE> that
+takes exactly one argument, returning true if that argument is false and
+vice versa.
+
+<P>In the last example, the procedure we really wanted to write was <CODE>buzz</CODE>,
+but we found it useful to define <CODE>divisible?</CODE> also.  It's quite common
+that the easiest way to solve some problem is to write a <EM>helper
+procedure</EM> to do part of the work.  In this case the helper procedure
+computes a function that's meaningful in itself, but sometimes you'll want
+to write procedures with names like <CODE>buzz-helper</CODE> that are useful only
+in the context of one particular problem.
+
+<P>Let's write a program that takes a word as its argument and returns the
+plural of that word.  Our first version will just put an &quot;s&quot; on the end:
+
+<P><PRE>(define (plural wd)
+  (word wd 's))
+
+&gt; (plural 'beatle)
+BEATLES
+
+&gt; (plural 'computer)
+COMPUTERS
+
+&gt; (plural 'fly)
+FLYS
+</PRE>
+
+<P>This works for most words, but not those that end in &quot;y.&quot; Here's
+version two:
+
+<P><PRE>(define (<A NAME="g89"></A>plural wd)
+  (if (equal? (last wd) 'y)
+      (word (bl wd) 'ies)
+      (word wd 's)))
+</PRE>
+
+<P>This isn't exactly right either; it thinks that the plural of
+&quot;boy&quot; is &quot;boies.&quot; We'll ask you to add some more rules in Exercise
+<A HREF="true.html#plurex">6.12</A>.
+
+<P><H2><CODE>If</CODE> Is a Special Form</H2>
+
+<P>There are a few subtleties that we haven't told you about yet.  First of
+all, <A NAME="g90"></A><CODE>if</CODE> is a <A NAME="g91"></A><A NAME="g92"></A>special form.  Remember that we're going to
+need the value of only one of its last two arguments.  It would be wasteful
+for Scheme to evaluate the other one.  So if you say
+
+<P><PRE>(if (= 3 3)
+    'sure
+    (factorial 1000))
+</PRE>
+
+<P><CODE>if</CODE> won't compute the factorial of 1000 before returning
+<CODE>sure</CODE>.
+
+<P>The rule is that <CODE>if</CODE> always evaluates its first argument.  If the value
+of that argument is true, then <CODE>if</CODE> evaluates its second argument and
+returns its value.  If the value of the first argument is false, then <CODE>if</CODE> evaluates its third argument and returns that value.
+
+<P><H2>So Are <CODE>And</CODE> and <CODE>Or</CODE></H2>
+
+<P><CODE>And</CODE> and <A NAME="g93"></A><CODE>or</CODE> are also <A NAME="g94"></A><A NAME="g95"></A>special forms.  They evaluate
+<A NAME="g96"></A> their arguments in order from left to right<A NAME="text3" HREF="true.html#ft3">[3]</A> and stop as soon as they can.  For <CODE>or</CODE>, this means
+returning true as soon as any of the arguments is true.  <CODE>And</CODE> returns
+false as soon as any argument is false.  This turns out to be useful in
+cases like the following:
+
+<P><PRE>(define (divisible? big small)
+  (= (remainder big small) 0))
+
+(define (<A NAME="g97"></A>num-divisible-by-4? x)
+  (and (number? x) (divisible? x 4)))
+
+&gt; (num-divisible-by-4? 16)
+#T
+
+&gt; (num-divisible-by-4? 6)
+#F
+
+&gt; (num-divisible-by-4? 'aardvark)
+#F
+
+&gt; (divisible? 'aardvark 4)
+ERROR: AARDVARK IS NOT A NUMBER
+</PRE>
+
+<P>We want to see if <CODE>x</CODE> is a number, and, if so, if it's
+divisible by <CODE>4</CODE>.  It would be an error to apply <CODE>divisible?</CODE> to a
+nonnumber.  If <CODE>and</CODE> were an ordinary procedure, the two tests (<CODE>number?</CODE> and <CODE>divisible?</CODE>) would both be evaluated before we would
+have a chance to pay attention to the result of the first one.  Instead, if
+<CODE>x</CODE> turns out not to be a number, our procedure will return <CODE>#f</CODE>
+without trying to divide it by <CODE>4</CODE>.
+
+<P><H2>Everything That Isn't False Is True</H2>
+
+<P><CODE>#T</CODE> isn't the only true value.  In fact, <EM>every</EM> value is
+considered true except for <CODE>#f</CODE>.
+
+<P><PRE>&gt; (if (+ 3 4) 'yes 'no)
+YES
+</PRE>
+
+<P>This allows us to have <EM>semipredicates</EM> that give
+slightly more information than just true or false.  For example, we can
+write an integer quotient procedure.  That is to say, our procedure will
+divide its first argument by the second, but only if the first is evenly
+divisible by the second.  If not, our procedure will return <CODE>#f</CODE>.
+
+<P><PRE>(define (<A NAME="g98"></A>integer-quotient big little)
+  (if (divisible? big little)
+      (/ big little)
+      #f))
+
+&gt; (integer-quotient 27 3)
+9
+
+&gt; (integer-quotient 12 5)
+#F
+</PRE>
+
+<P><CODE>And</CODE> and <CODE>or</CODE> are also semipredicates.  We've already explained
+that <CODE>or</CODE> returns a true result as soon as it evaluates a true
+argument.  The particular true value that <CODE>or</CODE> returns is the value of
+that first true argument:
+
+<P><PRE>&gt; (or #f 3 #f 4)
+3
+</PRE>
+
+<P><CODE>And</CODE> returns a true value only if all of its arguments are
+true.  In that case, it returns the value of the last argument:
+
+<P><PRE>&gt; (and 1 2 3 4 5)
+5
+</PRE>
+
+<P>As an example in which this behavior is useful, we can rewrite
+<CODE>integer-quotient</CODE> more tersely:
+
+<P><PRE>(define (integer-quotient big little)        ;; alternate version
+  (and (divisible? big little)
+       (/ big little)))
+</PRE>
+
+<P><H2>Decisions, Decisions, Decisions</H2>
+
+<P><CODE>If</CODE> is great for an either-or choice.  But sometimes there are several
+possibilities to consider:
+
+<P><PRE>(define (roman-value letter)
+  (if (equal? letter 'i)
+      1
+      (if (equal? letter 'v)
+          5
+          (if (equal? letter 'x)
+              10
+              (if (equal? letter 'l)
+                  50
+                  (if (equal? letter 'c)
+                      100
+                      (if (equal? letter 'd)
+                          500
+                          (if (equal? letter 'm)
+                              1000
+                              'huh?))))))))
+</PRE>
+
+<P>That's pretty hideous.  Scheme provides a shorthand notation for
+situations like this in which you have to choose from among several
+possibilities: the <A NAME="g99"></A><A NAME="g100"></A>special form <A NAME="g101"></A><CODE>cond</CODE>.
+<A NAME="cond"></A>
+
+<P><PRE>(define (<A NAME="g102"></A>roman-value letter)
+  (cond ((equal? letter 'i) 1)
+        ((equal? letter 'v) 5)
+        ((equal? letter 'x) 10)
+        ((equal? letter 'l) 50)
+        ((equal? letter 'c) 100)
+        ((equal? letter 'd) 500)
+        ((equal? letter 'm) 1000)
+        (else 'huh?)))
+</PRE>
+
+<P>The tricky thing about <CODE>cond</CODE> is that it doesn't use parentheses in quite
+<A NAME="g103"></A> the same way as the rest
+of Scheme.  Ordinarily, parentheses mean procedure invocation.  In <CODE>cond</CODE>, <EM>most</EM> of the parentheses still mean that, but <EM>some</EM> of
+them are used to group pairs of tests and results.  We've reproduced the
+same <CODE>cond</CODE> expression below, indicating the funny ones in boldface.
+
+<P><PRE>(define (roman-value letter)
+  (cond <STRONG><BIG>(</BIG></STRONG>(equal? letter 'i) 1<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'v) 5<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'x) 10<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'l) 50<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'c) 100<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'd) 500<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>(equal? letter 'm) 1000<STRONG><BIG>)</BIG></STRONG>
+        <STRONG><BIG>(</BIG></STRONG>else 'huh?<STRONG><BIG>)</BIG></STRONG> ))
+</PRE>
+
+<P><CODE>Cond</CODE> takes any number of arguments, each of which is <EM>two
+expressions</EM> inside a pair of parentheses.  Each argument is called a <EM><A NAME="g104"></A><A NAME="g105"></A>cond clause.</EM> In the example above, one typical clause is
+
+<P><PRE><STRONG><BIG>(</BIG></STRONG>(equal? letter 'l) 50<STRONG><BIG>)</BIG></STRONG>
+</PRE>
+
+<P>The outermost parentheses on that line enclose two expressions.
+The first of the two expressions (the <EM>condition</EM>) is taken as
+true or false, just like the first argument to <CODE>if</CODE>.  The second
+expression of each pair (the <EM>consequent</EM>) is a candidate for
+the return value of the entire <CODE>cond</CODE> invocation.
+
+<P><CODE>Cond</CODE> examines its arguments from left to right.  Remember that since
+<CODE>cond</CODE> is a special form, its arguments are not evaluated ahead of time.
+For each argument, <CODE>cond</CODE> evaluates the first of the two expressions
+within the argument.  If that value turns out to be true, then <CODE>cond</CODE>
+evaluates the second expression in the same argument, and returns that value
+without examining any further arguments.  But if the value is false, then
+<CODE>cond</CODE> does <EM>not</EM> evaluate the second expression; instead, it goes
+on to the next argument.
+
+<P>By convention, the last argument always starts with the word <A NAME="g106"></A><CODE>else</CODE>
+instead of an expression.  You can think of this as representing a true
+value, but <CODE>else</CODE> doesn't mean true in any other context; you're only
+allowed to use it as the condition of the last clause of a <CODE>cond</CODE>.<A NAME="text4" HREF="true.html#ft4">[4]</A>
+
+<P>Don't get into bad habits of thinking about the appearance of
+<CODE>cond</CODE> clauses in terms of &quot;two parentheses in a row.&quot;
+That's often the case, but not always.  For example, here is a procedure that
+translates Scheme true or false values (<CODE>#t</CODE> and <CODE>#f</CODE>)
+into more human-readable words <CODE>true</CODE> and <CODE>false</CODE>.
+
+<P><PRE>(define (<A NAME="g107"></A>truefalse value)
+  (cond (value 'true)
+	(else 'false)))
+
+&gt; (truefalse (= 2 (+ 1 1)))
+TRUE
+
+&gt; (truefalse (= 5 (+ 2 2)))
+FALSE
+</PRE>
+
+<P>When a <CODE>cond</CODE> tests several possible conditions, they might not
+be <A NAME="g108"></A><A NAME="g109"></A>mutually exclusive.<A NAME="text5"
+HREF="true.html#ft5">[5]</A> This can be either a source of error or an advantage in
+writing efficient programs.  The trick is to make the <EM>most
+restrictive</EM> test first.  For example, it would be an error to say
+
+<P><PRE>(cond ((number? (first sent)) &hellip)           ;; wrong
+      ((empty? sent) &hellip)
+      &hellip)
+</PRE>
+
+<P>because the first test only makes sense once you've already
+established that there <EM>is</EM> a first word of the sentence.
+On the other hand, you don't have to say
+
+<P><PRE>(cond ((empty? sent) &hellip)
+      ((and (not (empty? sent)) (number? (first sent))) &hellip)
+      &hellip)
+</PRE>
+
+<P>because you've already established that the sentence is nonempty
+if you get as far as the second clause.
+
+<P><H2><CODE>If</CODE> Is Composable</H2>
+
+<P>Suppose we want to write a <CODE>greet</CODE> procedure that works like this:
+
+<P><PRE>&gt; (greet '(brian epstein))
+(PLEASED TO MEET YOU BRIAN - HOW ARE YOU?)
+
+&gt; (greet '(professor donald knuth))
+(PLEASED TO MEET YOU PROFESSOR KNUTH - HOW ARE YOU?)
+</PRE>
+
+<P>The response of the program in these two cases is almost the same;
+the only difference is in the form of the person's name.
+
+<P>This procedure could be written in two ways:
+
+<P><PRE>(define (greet name)
+  (if (equal? (first name) 'professor)
+      (se '(pleased to meet you)
+	  'professor
+	  (last name)
+	  '(- how are you?))
+      (se '(pleased to meet you)
+	  (first name)
+	  '(- how are you?))))
+
+(define (greet name)
+  (se '(pleased to meet you)
+      (if (equal? (first name) 'professor)
+	  (se 'professor (last name))
+	  (first name))
+      '(- how are you?)))
+</PRE>
+
+<P>The second version avoids repeating the common parts of the
+response by using <CODE>if</CODE> within a larger expression.
+
+<P>Some people find it counterintuitive to use <CODE>if</CODE> as we did in the second
+version.  Perhaps the reason is that in some other programming languages,
+<CODE>if</CODE> is a &quot;command&quot; instead of a function like any other.  A mechanism
+that selects one part of a program to run, and leaves out another part, may
+seem too important to be a mere argument subexpression.  But in Scheme, the
+value returned by <EM>every</EM> function can be used as part of a larger
+expression.<A NAME="text6" HREF="true.html#ft6">[6]</A>
+
+<P>We aren't saying anything new here.  We've already explained the idea of
+composition of functions, and we're just making the same point again about
+<CODE>if</CODE>.  But we've learned that many students expect <CODE>if</CODE> to be an
+exception, so we're taking the opportunity to emphasize the point: There are
+no exceptions to this rule.
+
+<P><H2>Pitfalls</H2>
+
+<P>The biggest pitfall in this chapter is the unusual notation of <CODE>cond</CODE>.  Keeping track of the parentheses that mean function invocation, as
+usual, and the parentheses that just group the parts of a <CODE>cond</CODE> clause
+is tricky until you get accustomed to it.
+
+<P>Many people also have trouble with the asymmetry of the <A NAME="g110"></A><CODE>member?</CODE>
+predicate.  The first argument is something small; the second is something
+big.  (The order of arguments is the same as the order of a typical English
+sentence about membership:  &quot;Is Mick a member of the Beatles?&quot;)
+It seems pretty obvious when you look at an example in which both
+arguments are quoted constant values, but you can get in trouble when you
+define a procedure and use its parameters as the arguments to <CODE>member?</CODE>.
+Compare writing a procedure that says, &quot;does the letter E appear in this
+word?&quot; with one that says, &quot;is this letter a vowel?&quot;
+
+<P>Many people try to use <CODE>and</CODE> and <CODE>or</CODE> with the full flexibility
+of the corresponding English words.  Alas, Scheme is not English.  For
+example, suppose you want to know whether the argument to a procedure is
+either the word <CODE>yes</CODE> or the word <CODE>no</CODE>.  You can't say
+
+<P>
+<PRE>(equal? argument (or 'yes 'no))              ; wrong!
+</PRE>
+
+<P>This sounds promising:  &quot;Is the <CODE>argument</CODE> <CODE>equal</CODE> to
+the word <CODE>yes</CODE> <CODE>or</CODE> the word <CODE>no</CODE>?&quot; But the arguments to <CODE>or</CODE> must be true-or-false values, not things you want to check for equality
+with something else.  You have to make two separate equality tests:
+
+<P><PRE>(or (equal? argument 'yes) (equal? argument 'no))
+</PRE>
+
+<P>In this particular case, you could also solve the problem by saying
+
+<P><PRE>(member? argument '(yes no))
+</PRE>
+
+<P>but the question of trying to use <CODE>or</CODE> as if it were English
+comes up in other cases for which <CODE>member?</CODE> won't help.
+
+<P>This isn't exactly a pitfall, because it won't stop your program from
+working, but programs like
+
+<P><PRE>(define (odd? n)
+  (if (not (even? n)) #t #f))
+</PRE>
+
+<P>are redundant.  Instead, you could just say
+
+<P><PRE>(define (odd? n)
+  (not (even? n)))
+</PRE>
+
+<P>since the value of <CODE>(not (even? n))</CODE> is already <CODE>#t</CODE> or
+<CODE>#f</CODE>.
+
+<P><H2>Boring Exercises</H2>
+
+<P><B>6.1</B>&nbsp;&nbsp;What values are printed when you type these expressions to Scheme?  (Figure
+it out in your head before you try it on the computer.)
+
+<P><PRE>(cond ((= 3 4) '(this boy))
+      ((&lt; 2 5) '(nowhere man))
+      (else '(two of us)))
+
+(cond (empty? 3)
+      (square 7)
+      (else 9))
+
+(define (<A NAME="g111"></A>third-person-singular verb)
+  (cond ((equal? verb 'be) 'is)
+        ((equal? (last verb) 'o) (word verb 'es))
+        (else (word verb 's))))
+
+(third-person-singular 'go)
+</PRE>
+
+
+<P> 
+
+<B>6.2</B>&nbsp;&nbsp;What values are printed when you type these expressions to Scheme?  (Figure
+it out in your head before you try it on the computer.)
+
+<P><PRE>(or #f #f #f #t)
+
+(and #f #f #f #t)
+
+(or (= 2 3) (= 4 3))
+
+(not #f)
+
+(or (not (= 2 3)) (= 4 3))
+
+(or (and (= 2 3) (= 3 3)) (and (&lt; 2 3) (&lt; 3 4)))
+</PRE>
+
+<P><B>6.3</B>&nbsp;&nbsp;Rewrite the following procedure using a <CODE>cond</CODE> instead of the <CODE>if</CODE>s:
+
+<P><PRE>(define (<A NAME="g112"></A>sign number)
+  (if (&lt; number 0)
+      'negative
+      (if (= number 0)
+	  'zero
+	  'positive)))
+</PRE>
+
+<P>
+<B>6.4</B>&nbsp;&nbsp;Rewrite the following procedure using an <CODE>if</CODE> instead of the <CODE>cond</CODE>:
+
+<P><PRE>(define (<A NAME="g113"></A>utensil meal)
+  (cond ((equal? meal 'chinese) 'chopsticks)
+	(else 'fork)))
+</PRE>
+
+<P>
+<P>
+<H2>Real Exercises</H2>
+<P>
+Note: Writing helper procedures may be useful in solving some of these
+problems.
+
+<P><B>6.5</B>&nbsp;&nbsp;Write a procedure <A NAME="g114"></A><CODE>european-time</CODE> to convert a time from American
+AM/PM notation into European 24-hour notation.  Also
+write <A NAME="g115"></A><CODE>american-time</CODE>, which does the opposite:
+
+<P><PRE>&gt; (european-time '(8 am))
+8
+
+&gt; (european-time '(4 pm))
+16
+
+&gt; (american-time 21)
+(9 PM)
+
+&gt; (american-time 12)
+(12 PM)
+
+&gt; (european-time '(12 am))
+24
+</PRE>
+
+<P>Getting noon and midnight right is tricky.
+
+
+<P>
+<B>6.6</B>&nbsp;&nbsp;Write a predicate <A NAME="g116"></A><CODE>teen?</CODE> that returns true if its argument is between
+13 and 19.
+
+
+<P>
+<B>6.7</B>&nbsp;&nbsp;Write a procedure <A NAME="g117"></A><CODE>type-of</CODE> that takes anything as its argument and
+returns one of the words <CODE>word</CODE>, <CODE>sentence</CODE>, <CODE>number</CODE>, or
+<CODE>boolean</CODE>:
+
+<P><PRE>&gt; (type-of '(getting better))
+SENTENCE
+
+&gt; (type-of 'revolution)
+WORD
+
+&gt; (type-of (= 3 3))
+BOOLEAN
+</PRE>
+
+<P>(Even though numbers are words, your procedure should return <CODE>number</CODE> if its argument is a number.)
+
+<P>Feel free to check for more specific types, such as &quot;positive integer,&quot;
+if you are so inclined.
+
+
+<P>
+<B>6.8</B>&nbsp;&nbsp;Write a procedure <A NAME="g118"></A><CODE>indef-article</CODE> that works like this:
+<PRE>&gt; (indef-article 'beatle)
+(A BEATLE)
+
+&gt; (indef-article 'album)
+(AN ALBUM)
+</PRE>
+
+<P>Don't worry about silent initial consonants like the <CODE>h</CODE> in <CODE>hour</CODE>.
+
+
+<P>
+<B>6.9</B>&nbsp;&nbsp;Sometimes you must choose the singular or the plural of a word:  <CODE>1 book</CODE> but <CODE>2 books</CODE>.  Write a procedure <A NAME="g119"></A><CODE>thismany</CODE> that takes
+two arguments, a number and a singular noun, and combines them appropriately:
+
+<P><PRE>&gt; (thismany 1 'partridge)
+(1 PARTRIDGE)
+
+&gt; (thismany 3 'french-hen)
+(3 FRENCH-HENS)
+</PRE>
+
+
+<P>
+<P>
+<B>6.10</B>&nbsp;&nbsp;Write a procedure <A NAME="g120"></A><CODE>sort2</CODE> that takes as its argument a sentence
+containing two numbers.  It should return a sentence containing the same two
+numbers, but in ascending order:
+
+<P><PRE>&gt; (sort2 '(5 7))
+(5 7)
+
+&gt; (sort2 '(7 5))
+(5 7)
+</PRE>
+
+<P>
+<B>6.11</B>&nbsp;&nbsp;Write a predicate <A NAME="g121"></A><CODE>valid-date?</CODE> that takes three numbers as arguments,
+representing a month, a day of the month, and a year.  Your procedure should
+return <CODE>#t</CODE> if the numbers represent a valid date (e.g., it isn't the
+31st of September).  February has 29 days if the year is divisible by 4,
+except that if the year is divisible by 100 it must also be divisible by 400.
+
+<P><PRE>&gt; (valid-date? 10 4 1949)
+#T
+
+&gt; (valid-date? 20 4 1776)
+#F
+
+&gt; (valid-date? 5 0 1992)
+#F
+
+&gt; (valid-date? 2 29 1900)
+#F
+
+&gt; (valid-date? 2 29 2000)
+#T
+</PRE>
+
+<P>
+<B>6.12</B>&nbsp;&nbsp;Make <A NAME="g122"></A><CODE>plural</CODE> handle correctly words that end in <CODE>y</CODE> but have a
+vowel before the <CODE>y</CODE>, such as <CODE>boy</CODE>.  Then teach it about words that
+end in <CODE>x</CODE> (box).  What other special cases can you find?
+
+<P><A NAME="plurex"></A>
+
+
+<P>
+<B>6.13</B>&nbsp;&nbsp;Write a better <A NAME="g123"></A><CODE>greet</CODE> procedure that understands as many different
+kinds of names as you can think of:
+
+<P><PRE>&gt; (greet '(john lennon))
+(HELLO JOHN)
+
+&gt; (greet '(dr marie curie))
+(HELLO DR CURIE)
+
+&gt; (greet '(dr martin luther king jr))
+(HELLO DR KING)
+
+&gt; (greet '(queen elizabeth))
+(HELLO YOUR MAJESTY)
+
+&gt; (greet '(david livingstone))
+(DR LIVINGSTONE I PRESUME?)
+</PRE>
+
+
+<P>
+<B>6.14</B>&nbsp;&nbsp;Write a procedure <A NAME="g124"></A><CODE>describe-time</CODE> that takes a number of seconds as its
+argument and returns a more useful description of that amount of time:
+<A NAME="desctime"></A>
+
+<P><PRE>&gt; (describe-time 45)
+(45 SECONDS)
+
+&gt; (describe-time 930)
+(15.5 MINUTES)
+
+&gt; (describe-time 30000000000)
+(9.506426344208686 CENTURIES)
+</PRE>
+
+<P>
+
+<HR>
+<A NAME="ft1" HREF="true.html#text1">[1]</A> In <EM>some</EM>
+versions of Scheme, the <A NAME="g67"></A><A NAME="g68"></A>empty sentence is considered false.  That
+is, <CODE>()</CODE> and <CODE>#f</CODE> may be the same thing.  The reason that we can't
+be definite about this point is that older versions of Scheme follow the
+traditional Lisp usage, in which the empty sentence is false, but since then
+a standardization committee has come along and insisted that the two values
+should be different.  In this book we'll consider them as different, but
+we'll try to avoid examples in which it matters.  The main point is that you
+shouldn't be surprised if you see something like this:
+
+<P><PRE>&gt; (= 3 4)
+()
+</PRE>
+
+<P>in the particular implementation of Scheme that you're using.
+<P>
+<A NAME="ft2" HREF="true.html#text2">[2]</A> Why is it called that?  Think about an English
+sentence, such as &quot;Ringo is a drummer.&quot; As you may remember from elementary
+school, &quot;Ringo&quot; is the <EM>subject</EM> of that sentence, and &quot;is a
+drummer&quot; is the <EM>predicate.</EM> That predicate could be truthfully
+attached to some subjects but not others.  For example, it's true of &quot;Neil
+Peart&quot; but not of &quot;George Harrison.&quot; So the predicate &quot;is a drummer&quot;
+can be thought of as a function whose value is true or false.<P>
+<A NAME="ft3" HREF="true.html#text3">[3]</A> Since you
+can start a new line in the middle of an expression, in some cases the
+arguments will be &quot;top to bottom&quot; rather than &quot;left to right,&quot; but don't
+forget that Scheme doesn't care about line breaks.  That's why Lisp
+programmers always talk as if their programs were written on one enormously
+long line.<P>
+<A NAME="ft4" HREF="true.html#text4">[4]</A> What if you don't use an <CODE>else</CODE>
+clause at all?  If none of the clauses has a true condition, then the return
+value is unspecified.  In other words, always use <CODE>else</CODE>.<P>
+<A NAME="ft5" HREF="true.html#text5">[5]</A> Conditions are mutually
+exclusive if only one of them can be true at a time.<P>
+<A NAME="ft6" HREF="true.html#text6">[6]</A> Strictly speaking, since the argument expressions to a
+special form aren't evaluated, <CODE>if</CODE> is a function whose domain is
+expressions, not their values.  But many special forms, including <CODE>if</CODE>,
+<CODE>and</CODE>, and <CODE>or</CODE>, are designed to act as if they were ordinary
+functions, the kind whose arguments Scheme evaluates in advance.  The only
+difference is that it is sometimes possible for Scheme to figure out the
+correct return value after evaluating only some of the arguments.  Most of
+the time we'll just talk about the domains and ranges of these special forms
+as if they were ordinary functions.<P>
+<P><A HREF="../ss-toc2.html">(back to Table of Contents)</A><P>
+<A HREF="../ssch5/words.html"><STRONG>BACK</STRONG></A>
+chapter thread <A HREF="../ssch7/variables.html"><STRONG>NEXT</STRONG></A>
+
+<P>
+<ADDRESS>
+<A HREF="../index.html">Brian Harvey</A>, 
+<CODE>bh@cs.berkeley.edu</CODE>
+</ADDRESS>
+</BODY>
+</HTML>