about summary refs log blame commit diff stats
path: root/js/games/nluqo.github.io/~bh/ssch4/defining.html
blob: 4dbef0b96f106a3edbdfff9adbea4ad0b783f54e (plain) (tree)
562a9a5 ^












































































Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
'#n169'>169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754

















































































































































































































































































































































































































































































































































































































































































































































































                                                                                                                                                                                                                                                   
<P>
<A NAME="plugboard"></A>
<P>
<CENTER><IMG SRC="../ss-pics/plugboard.jpg" ALT="figure: plugboard"></CENTER><P><CENTER>In the old days, they &quot;defined procedures&quot; like this.
</CENTER><P>

<HTML>
<HEAD>
<TITLE>Simply Scheme: Introducing Computer Science ch 4: Defining Your Own Procedures</TITLE>
</HEAD>
<BODY>
<HR>
<CITE>Simply Scheme:</CITE>
<CITE>Introducing Computer Science</CITE> 2/e Copyright (C) 1999 MIT
<H2>Chapter 4</H2>
<H1>Defining Your Own Procedures</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/ssch04.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="../ssch3/people.html"><STRONG>BACK</STRONG></A>
chapter thread <A HREF="../ssch5/words.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>Until now we've been using procedures that Scheme already knows when you
begin working with it.  In this chapter you'll find out how to create
new procedures.

<P><H2>How to Define a Procedure</H2>

<P>A Scheme program consists of one or more <EM>procedures.</EM> A procedure is
a description of the process by which a computer can work out some result
that we want.  Here's how to define a procedure that returns the square of
its argument:

<P><PRE>(define (<A NAME="g1"></A>square x)
  (* x x))
</PRE>

<P>(The value returned by <A NAME="g2"></A><CODE>define</CODE> may differ depending on the
version of Scheme you're using.  Many versions return the name of the
procedure you're defining, but others return something else.  It doesn't
matter, because when you use <CODE>define</CODE> you aren't interested in the
returned value, but rather in the fact that Scheme remembers the new
definition for later use.)

<P>This is the definition of a procedure called <CODE>square</CODE>.  <CODE>Square</CODE>
takes one argument, a number, and it returns the square of that number.
Once you have defined <CODE>square</CODE>, you can use it just the same way as you
use primitive procedures:

<P><PRE>&gt; (square 7)
49

&gt; (+ 10 (square 2))
14

&gt; (square (square 3))
81
</PRE>

<P>This procedure definition has four parts.  The first is the word <CODE>define</CODE>, which indicates that you are defining something.  The second and
third come together inside parentheses: the name that you want to give the
procedure and the name(s) you want to use for its argument(s).  This
arrangement was chosen by the designers of Scheme because it looks like the
form in which the procedure will be invoked.  That is, <CODE>(square x)</CODE> looks
like <CODE>(square 7)</CODE>.  The fourth part of the definition is the <EM>body:</EM> an expression whose value provides the function's return value.

<P><CENTER><IMG SRC="../ss-pics/definition.jpg" ALT="figure: definition"></CENTER>

<P><H2>Special Forms</H2>

<P><CODE>Define</CODE> is a <EM><A NAME="g3"></A><A NAME="g4"></A>special form,</EM> an exception to the
evaluation rule we've been going on about.<A NAME="text1" HREF="defining.html#ft1">[1]</A> Usually, an expression represents a procedure invocation, so
the general rule is that Scheme first evaluates all the subexpressions, and
then applies the resulting procedure to the resulting argument values.  The
specialness of special forms is that Scheme <EM>doesn't</EM> evaluate all the
subexpressions.  Instead, each special form has its own particular
evaluation rule.  For example, when we defined <CODE>square</CODE>, no
part of the definition was evaluated: not <CODE>square</CODE>, not <CODE>x</CODE>, and
not <CODE>(* x x)</CODE>.  It wouldn't make sense to evaluate <CODE>(square x)</CODE>
because you can't invoke the <CODE>square</CODE> procedure before you define it!

<P>It would be possible to describe special forms using the following model:
&quot;Certain procedures want their arguments unevaluated, and Scheme recognizes
them.  After refraining from evaluating <CODE>define</CODE>'s arguments, for
example, Scheme invokes the <CODE>define</CODE> procedure with those unevaluated
arguments.&quot; But in fact the designers of Scheme chose to think about it
differently.  The entire special form that starts with <CODE>define</CODE> is just a
completely different kind of thing from a procedure call.  In Scheme there
is no procedure named <CODE>define</CODE>.  In fact, <CODE>define</CODE> is not the name
of anything at all:

<P><PRE>&gt; +
#&lt;PRIMITIVE PROCEDURE +>

&gt; define
ERROR - INVALID CONTEXT FOR KEYWORD DEFINE
</PRE>

<P>Nevertheless, in this book, unless it's really important to make
the distinction, we'll talk as if there were a procedure called <CODE>define</CODE>.
For example, we'll talk about &quot;<CODE>define</CODE>'s arguments&quot; and &quot;the value
returned by <CODE>define</CODE>&quot; and &quot;invoking <CODE>define</CODE>.&quot;

<P><H2>Functions and Procedures</H2>

<P>Throughout most of this book, our procedures will describe processes that
<A NAME="g5"></A>
<A NAME="g6"></A>
compute <EM>functions.</EM> A function is a connection between some values
you already know and a new value you want to find out.  For example, the
<EM>square</EM> function takes a number, such as 8, as its input value and
returns another number, 64 in this case, as its output value.  The <EM>plural</EM> function takes a noun, such as &quot;computer,&quot; and returns another
word, &quot;computers&quot; in this example.  The technical term for the function's
input value is its <EM>argument.</EM> A function may take more than one
argument; for example, the <CODE>remainder</CODE> function takes two arguments,
such as 12 and 5.  It returns one value, the remainder on dividing the first
argument by the second (in this case, 2).

<P>We said earlier that a procedure is &quot;a description of the process by which
a computer can work out some result that we want.&quot; What do we mean by <EM>process</EM>?  Consider these two definitions:

<P><P><P><CENTER><EM>f</EM>(<EM>x</EM>)=3<EM>x</EM>+12<BR>
<EM>g</EM>(<EM>x</EM>)=3(<EM>x</EM>+4)<P></CENTER>

The two definitions call for different arithmetic operations.  For
example, to compute <EM>f</EM>(8) we'd multiply 8 by 3, then add 12 to the result.
To compute <EM>g</EM>(8), we'd add 4 to 8, then multiply the result by 3.  But we
get the same answer, 36, either way.  These two equations describe different
<EM>processes,</EM> but they compute the same <EM>function.</EM> The function
is just the association between the starting value(s) and the resulting
value, no matter how that result is computed.  In Scheme we could say

<P><PRE>(define (f x)
  (+ (* 3 x) 12))

(define (g x)
  (* 3 (+ x 4)))
</PRE>

<P>and we'd say that <CODE>f</CODE> and <CODE>g</CODE> are two procedures that
represent the same function.

<P>In real life, functions are not always represented by procedures.  We could
represent a function by a <EM>table</EM> showing all its possible values,
like this:

<P><P><CENTER><TABLE><TR><TD>Alabama<TD>&nbsp;&nbsp;&nbsp;Montgomery
<TR><TD>Alaska<TD>&nbsp;&nbsp;&nbsp;Juneau
<TR><TD>Arizona<TD>&nbsp;&nbsp;&nbsp;Phoenix
<TR><TD>Arkansas<TD>&nbsp;&nbsp;&nbsp;Little Rock
<TR><TD>California<TD>&nbsp;&nbsp;&nbsp;Sacramento
<TR><TD>&hellip;<TD>&nbsp;&nbsp;&nbsp;&hellip;</TABLE></CENTER>

This table represents the State Capital function; we haven't shown
all the lines of the complete table, but we could.  There are only a finite
number of U.S. states.  Numeric functions can also be represented by <EM>graphs,</EM> as you probably learned in high school algebra.  In this book our
focus is on the representation of functions by procedures.  The only reason
for showing you this table example is to clarify what we mean when we say
that a function <EM>is represented by</EM> a procedure, rather than that a
function <EM>is</EM> the procedure.

<P>We'll say &quot;the procedure <CODE>f</CODE>&quot; when we want to discuss the operations
we're telling Scheme to carry out.  We'll say &quot;the function represented by
<CODE>f</CODE>&quot; when our attention is focused on the value returned, rather than
on the mechanism.  (But we'll often abbreviate that lengthy second phrase
with &quot;the function <CODE>f</CODE>&quot; unless the context is especially
confusing.)<A NAME="text2" HREF="defining.html#ft2">[2]</A>

<P><H2>Argument Names versus Argument Values</H2>

<P><P><A NAME="alice"></A>
<BLOCKQUOTE>

<P>&quot;It's long,&quot; said the Knight, &quot;but it's very, <EM>very</EM> beautiful.
Everybody that hears me sing it&mdash;either it brings the <EM>tears</EM> into
their eyes, or else&mdash;&quot;

<P>&quot;Or else what?&quot; said Alice, for the Knight had made a sudden pause.

<P>&ldquo;Or else it doesn't, you know.  The name of the song is called &lsquo;<EM>Haddock's Eyes.</EM>&rsquo;&thinsp;&rdquo;

<P>&quot;Oh, that's the name of the song, is it?&quot; Alice said, trying to feel
interested.

<P>&quot;No, you don't understand,&quot; the Knight said, looking a little vexed.
&ldquo;That's what the name is <EM>called.</EM> The name really is &lsquo;<EM>The Aged
Aged Man.</EM>&rsquo&thinsp;&rdquo;

<P>&ldquo;Then I ought to have said &lsquo;That's what the <EM>song</EM> is called&rsquo;?&rdquo; 
Alice corrected herself.

<P>&ldquo;No, you oughtn't; that's quite another thing!  The <EM>song</EM> is called
&lsquo<EM>Ways And Means</EM>&rsquo: but that's only what it's <EM>called,</EM> you
know!&rdquo;

<P>&quot;Well, what <EM>is</EM> the song, then?&quot; said Alice, who was by this time
completely bewildered.

<P>&quot;I was coming to that,&quot; the Knight said.  &ldquo;The song really is &lsquo<EM>A-sitting On A Gate</EM>&rsquo;: and the tune's my own invention.&rdquo;

<P><A NAME="g7"></A>Lewis Carroll, <EM>Through the Looking-Glass, and What
Alice Found There</EM>

<P></BLOCKQUOTE><P>
Notice that when we <EM>defined</EM> the <CODE>square</CODE> procedure we gave a <EM>name,</EM> <CODE>x</CODE>, for its argument.  By contrast, when we <EM>invoked</EM>
<CODE>square</CODE> we provided a <EM>value</EM> for the argument (e.g., <CODE>7</CODE>).
The word <CODE>x</CODE> is a &quot;place holder&quot; in the definition that stands for
whatever value you use when you call the procedure.  So you can read the
definition of <CODE>square</CODE> as saying, &quot;In order to <CODE>square</CODE> a number,
multiply <EM>that number</EM> by <EM>that number.</EM>&quot; The name <CODE>x</CODE>
holds the place of the particular number that you mean.

<P>Be sure you understand this distinction between defining a procedure and
calling it.  A procedure represents a general technique that can be applied
to many specific cases.  We don't want to build any particular case into the
procedure definition; we want the definition to express the general nature of
the technique.  You wouldn't want a procedure that only knew how to take the
square of 7.  But when you actually get around to using <CODE>square</CODE>, you have
to be specific about which number you're squaring.

<P>The name for the name of an argument (whew!) is <EM><A NAME="g8"></A><A NAME="g9"></A>formal parameter.</EM> In our <CODE>square</CODE> example, <CODE>x</CODE>
is the formal parameter.  (You may hear people say either &quot;formal&quot;
alone or &quot;parameter&quot; alone when they're feeling lazy.)  The
technical term for the actual value of the argument is the <EM><A NAME="g10"></A><A NAME="g11"></A>actual argument.</EM> In a case like

<P>
<PRE>(square (+ 5 9))
</PRE>


<P>
you may want to distinguish the <EM><A NAME="g12"></A><A NAME="g13"></A>actual argument expression</EM> <CODE>(+ 5 9)</CODE> from the <EM><A NAME="g14"></A><A NAME="g15"></A>actual argument value</EM> 14.  Most of the time it's perfectly clear
what you mean, and you just say &quot;argument&quot; for all of these things, but
right now when you're learning these ideas it's important to be able to talk
more precisely.

<P>
The <CODE>square</CODE> procedure takes one argument.  If a procedure requires more
than one argument, then the question arises, which actual argument goes with
which formal parameter?  The answer is that they go in the order in which
you write them, like this:

<P><PRE>(define (f a b)
  (+ (* 3 a) b))

&gt; (f 5 8)
23

&gt; (f 8 5)
29
</PRE>

<P><H2>Procedure as Generalization</H2>
<A NAME="g16"></A>

<P>What's the average of 17 and 25?  To answer this question you could add the
two numbers, getting 42, and divide that by two, getting 21.  You could ask
Scheme to do this for you:

<P><PRE>&gt; (/ (+ 17 25) 2)
21
</PRE>

<P>What's the average of 14 and 68?

<P><PRE>&gt; (/ (+ 14 68) 2)
41
</PRE>

<P>Once you understand the technique, you could answer any such question by
typing an expression of the form

<P><PRE>(/ (+  ______  ______ ) 2)
</PRE>

<P>to Scheme.

<P>But if you're going to be faced with more such problems, an obvious next
step is to <EM>generalize</EM> the technique by defining a procedure:

<P><PRE>(define (<A NAME="g17"></A>average a b)
  (/ (+ a b) 2))
</PRE>

<P>With this definition, you can think about the next problem that
comes along in terms of the problem itself, rather than in terms of the
steps required for its solution:

<P><PRE>&gt; (average 27 4)
15.5
</PRE>

<P>This is an example of what we meant when we defined
&quot;abstraction&quot; as noticing a pattern and giving it a name.
It's not so different from the naming of such patterns in English;
when someone invented the name &quot;average&quot; it was, probably, after
noticing that it was often useful to find the value halfway between
two other values.

<P>This naming process is more important than it sounds, because once we have a
name for some idea, we can use that idea without thinking about its pieces.
For example, suppose that you want to know not only the average of some
numbers but also a measure of whether the numbers are clumped together close
to the average, or widely spread out.  Statisticians have developed the
&quot;standard deviation&quot; as a measure of this second property.  You'd rather
not have to think about this mysterious formula:

<P><P><CENTER><IMG SRC="math1.gif" ALT="math display"></CENTER><P>

<P>but you'd be happy to use a procedure <CODE>standard-deviation</CODE>
that you found in a collection of statistical programs.

<P>After all, there's no law of nature that says computers automatically know
how to add or subtract.  You could imagine having to instruct Scheme to
compute the sum of two large numbers digit by digit, the way you did in
elementary school.  But instead someone has &quot;taught&quot; your computer how to
add before you get to it, giving this technique the name <CODE>+</CODE> so that you
can ask for the sum of two numbers without thinking about the steps required.
By inventing <CODE>average</CODE> or <CODE>standard-deviation</CODE> we are extending the
repertoire of computations that you can ask for without concerning yourself
with the details.

<P><H2>Composability</H2>

<P>We've suggested that a procedure you define, such as <CODE>average</CODE>, is
<A NAME="g18"></A>
<A NAME="g19"></A>
essentially similar to one that's built into Scheme, such as <CODE>+</CODE>.
In particular, the rules for building expressions are the same whether
the building blocks are primitive procedures or defined procedures.

<P><PRE>&gt; (average (+ 10 8) (* 3 5))
16.5

&gt; (average (average 2 3) (average 4 5))
3.5

&gt; (sqrt (average 143 145))
12
</PRE>

<P>Any return value can be used as an end in itself, as the return
value from <CODE>sqrt</CODE> was used in the last of these examples, or it can
provide an argument to another procedure, as the return value from
<CODE>*</CODE> was used in the first of these examples.

<P>These small examples may seem arbitrary, but the same idea, composition of
functions, is the basis for all Scheme programming.  For example, the
complicated formula we gave for standard deviation requires computing the
squares of several numbers.  So if we were to write a <CODE>standard-deviation</CODE> procedure, it would invoke <CODE>square</CODE>.

<P><H2>The Substitution Model</H2>

<P>We've paid a lot of attention to the details of formal parameters and actual
arguments, but we've been a little handwavy<A NAME="text3" HREF="defining.html#ft3">[3]</A> about how a procedure actually computes a value when you invoke it.

<P>We're going to explain what happens when you invoke a user-defined procedure.
Every explanation is a story.  No story tells the entire truth, because there
are always some details left out.  A <EM>model</EM> is a story that
has just enough detail to help you understand whatever it's trying to explain
but not so much detail that you can't see the forest for the trees.

<P>Today's story is about the <EM>substitution</EM> model.  When a
procedure is invoked, the goal is to carry out the computation described in
its body.  The problem is that the body is written in terms of the formal
parameters, while the computation has to use the actual argument values.  So
what Scheme needs is a way to associate actual argument values with formal
parameters.  It does this by making a new copy of the body of the procedure,
in which it substitutes the argument values for every appearance of the
formal parameters, and then evaluating the resulting expression.  So, if
you've defined <CODE>square</CODE> with 

<P><PRE>(define (square x)
  (* x x))
</PRE>

<P>then the body of <CODE>square</CODE> is <CODE>(* x x)</CODE>.  When you want to
know the square of a particular number, as in <CODE>(square 5)</CODE>, Scheme
substitutes the 5 for <CODE>x</CODE> everywhere in the body of square and evaluates
the expression.  In other words, Scheme takes

<P><PRE>(* x x)
</PRE>

<P>then does the substitution, getting

<P><PRE>(* 5 5)
</PRE>

<P>and then evaluates that expression, getting 25.

<P>If you just type <CODE>(* x x)</CODE> into Scheme, you will get an error message
complaining that <CODE>x</CODE> doesn't mean anything.  Only after the substitution
does this become a meaningful expression.

<P>By the way, when we talk about &quot;substituting into the body,&quot; we don't mean
that the procedure's definition is changed in any permanent way.  The body of
the procedure doesn't change; what happens, as we said before, is that Scheme
constructs a new expression that looks like the body, except for the
substitutions.<A NAME="text4" HREF="defining.html#ft4">[4]</A>

<P>There are little people who specialize in <CODE>square</CODE>, just as there
are little people who specialize in <CODE>+</CODE> and <CODE>*</CODE>.  The difference is
that the little people who do primitive procedures can do the work &quot;in their
head,&quot; all at once.  The little people who carry out user-defined procedures
have to go through this substitution business we're talking about here.
Then they hire other little people to help evaluate the resulting expression,
just as Alonzo hires people to help him evaluate the expressions you type
directly to Scheme.

<P>Let's say Sam, a little person who specializes in <CODE>square</CODE>, has been
asked to compute <CODE>(square 6)</CODE>.  Sam carries out the substitution, and is
left with the expression <CODE>(* 6 6)</CODE> to evaluate.  Sam then hires Tessa, a
multiplication specialist, to evaluate this new expression.  Tessa tells Sam
that her answer is 36, and, because the multiplication is the entire problem
to be solved, this is Sam's answer also.

<P>Here's another example:

<P><PRE>(define (<A NAME="g20"></A>hypotenuse a b)
  (sqrt (+ (square a) (square b))))

&gt; (hypotenuse 5 12)
</PRE>

<P> Suppose Alonzo hires Harry to compute this expression.
Harry must first substitute the actual argument values (5 and 12) into the
body of <CODE>hypotenuse</CODE>:

<P><PRE>(sqrt (+ (square 5) (square 12)))
</PRE>

<P>Now he evaluates that expression, just as Alonzo would evaluate it
if you typed it at a Scheme prompt.  That is, Harry hires four little
people: one <CODE>sqrt</CODE> expert, one <CODE>+</CODE> expert, and two <CODE>square</CODE>
experts.<A NAME="text5" HREF="defining.html#ft5">[5]</A> In particular, some little
person has to evaluate <CODE>(square 5)</CODE>, by substituting 5 for <CODE>x</CODE> in
the body of <CODE>square</CODE>, as in the earlier example.  Similarly, we
substitute 12 for <CODE>x</CODE> in order to evaluate <CODE>(square 12)</CODE>:

<P><PRE>(hypotenuse 5 12)                   ; substitute into HYPOTENUSE body
(sqrt (+ (square 5) (square 12)))   ; substitute for (SQUARE 5)
         (* 5 5)
         25
(sqrt (+ 25         (square 12)))   ; substitute for (SQUARE 12)
                    (* 12 12)
                    144
(sqrt (+ 25         144))
      (+ 25         144)            ; combine the results as before
      169
(sqrt 169)
13
</PRE>

<P>Don't forget, in the heady rush of learning about the substitution
model, what you already knew from before:  Each piece of this computation is
done by a little person, and some other little person is waiting for the
result.  In other words, the substitution model tells us how <EM>each
compound procedure</EM> is carried out, but doesn't change our picture of the
way in which procedure invocations are <EM>composed</EM> into larger
expressions.

<P><H2>Pitfalls</H2>

<P>Don't forget that a function can have only <EM>one</EM> return value.
For example, here's a program that's supposed to return the sum of the
squares of its two arguments:

<P><PRE>(define (sum-of-squares x y)                 ;; wrong!
  (square x)
  (square y))
</PRE>

<P>The problem is that the body of this procedure has two expressions,
instead of just one.  As it turns out, Scheme just ignores the value of the
first expression in cases like this, and returns the value of the last one.
What the programmer wants is the <EM>sum</EM> of these two values, so the
procedure should say

<P><PRE>(define (sum-of-squares x y)
  (+ (square x)
     (square y)))
</PRE>

<P>Another pitfall comes from thinking that a procedure call changes the
value of a parameter.  Here's a faulty program that's supposed to compute
the function described by <EM>f</EM>(<EM>x</EM>)=3<EM>x</EM>+10:

<P><PRE>(define (f x)                                ;; wrong!
  (* x 3)
  (+ x 10))
</PRE>

<P>Again, the first expression has no effect and Scheme will just
return the value <EM>x</EM>+10.<A NAME="text6" HREF="defining.html#ft6">[6]</A>

<P>A very common pitfall in Scheme comes from choosing the name of
a procedure as a parameter.  It doesn't come up very often with
procedures like the ones in this chapter whose domains and ranges
are both numbers, but it will be more likely later.  If you have a
program like this:

<P><PRE>(define (square x)
  (* x x))

(define (area square)                        ;; wrong!
  (square square))
</PRE>

<P>then you'll get in trouble when you invoke the procedure, for
example, by saying <CODE>(area 8)</CODE>.  The <CODE>area</CODE> little person will
substitute <CODE>8</CODE> for <CODE>square</CODE> everywhere in the procedure definition,
leaving you with the expression <CODE>(8 8)</CODE> to evaluate.  That expression
would mean to apply the procedure <CODE>8</CODE> to the argument <CODE>8</CODE>, but
<CODE>8</CODE> isn't a procedure, so an error message results.

<P>It isn't a problem if the formal parameter is the name of a procedure that
you don't use inside the body.  The problem arises when you try to use the
same name, e.g., <CODE>square</CODE>, with two meanings within a single procedure.
But special forms are an exception; you can never use the name of a special
form as a parameter.

<P>A similar problem about name conflicts comes up if you try to
use a keyword (the name of a special form, such as <CODE>define</CODE>) as
some other kind of name&mdash;either a formal parameter or the name of a
procedure you're defining.  We're listing this separately because the
result is likely to be different.  Instead of getting the wrong value
substituted, as above, you'll probably see a special error message
along the lines of &quot;improper use of keyword.&quot;

<P>Formal parameters <EM>must</EM> be words.  Some people try to write
procedures that have compound expressions as the formal parameters, like this:

<P><PRE>(define (f (+ 3 x) y)                        ;; wrong!
  (* x y))
</PRE>

<P>Remember that the job of the procedure definition is only to
provide a <EM>name</EM> for the argument.  The <EM>actual</EM> argument isn't
pinned down until you invoke the procedure.  People who write programs like
the one above are trying to make the procedure definition do some of the job
of the procedure invocation.

<P><H2>Boring Exercises</H2>

<P><B>4.1</B>&nbsp;&nbsp;Consider this procedure:

<P><PRE>(define (ho-hum x y)
  (+ x (* 2 y)))
</PRE>

<P>Show the substitution that occurs when you evaluate 

<P><PRE>(ho-hum 8 12)
</PRE>

<P>
<B>4.2</B>&nbsp;&nbsp;Given the following procedure:

<P><PRE>(define (yawn x)
  (+ 3 (* x 2)))
</PRE>

<P>list all the little people that are involved in evaluating

<P><PRE>(yawn (/ 8 2))
</PRE>

<P>(Give their names, their specialties, their arguments,
who hires them, and what they do with their answers.)


<P>
<B>4.3</B>&nbsp;&nbsp;Here are some procedure definitions.  For each one, describe the function in
English, show a sample invocation, and show the result of that invocation.

<P><PRE>(define (f x y) (- y x))

(define (identity x) x)

(define (three x) 3)

(define (seven) 7)

(define (magic n)
  (- (/ (+ (+ (* 3 n)
              13)
           (- n 1))
        4)
     3))
</PRE>


<P>
<H2>Real Exercises</H2>

<P><B>4.4</B>&nbsp;&nbsp;Each of the following procedure definitions has an error of some kind.
Say what's wrong and why, and fix it:

<P><PRE>(define (sphere-volume r)
  (* (/ 4 3) 3.141592654)
  (* r r r))

(define (next x)
  (x + 1))

(define (square)
  (* x x))

(define (triangle-area triangle)
  (* 0.5 base height))

(define (sum-of-squares (square x) (square y))
  (+ (square x) (square y)))
</PRE>


<P>
<B>4.5</B>&nbsp;&nbsp;Write a procedure to convert a temperature from Fahrenheit to Celsius, and
another to convert in the other direction.  The two formulas
are <EM>F</EM>=<SUP><SMALL><SMALL>9</SMALL></SMALL></SUP>&frasl;<SUB><SMALL><SMALL>5</SMALL></SMALL></SUB><EM>C</EM>+32 and <EM>C</EM>=<SUP><SMALL>5</SMALL></SUP>&frasl;<SUB><SMALL>9</SMALL></SUB>(<EM>F</EM>-32).


<P>
<B>4.6</B>&nbsp;&nbsp;Define a procedure <CODE>fourth</CODE> that computes the fourth power of its
argument.  Do this two ways, first using the multiplication function,
and then using <CODE>square</CODE> and not (directly) using multiplication.


<P>
<B>4.7</B>&nbsp;&nbsp;Write a procedure that computes the absolute value of its argument by
finding the square root of the square of the argument.


<P>
<B>4.8</B>&nbsp;&nbsp;&quot;Scientific notation&quot; is a way to represent very small or very large
numbers by combining a medium-sized number with a power of 10.  For example,
5&times;10<SUP><SMALL>7</SMALL></SUP> represents the number 50000000, while 3.26&times;10<SUP><SMALL>-9</SMALL></SUP>
represents 0.00000000326 in scientific notation.  Write a procedure
<CODE>scientific</CODE> that takes two arguments, a number and an exponent of 10,
and returns the corresponding value:

<P><PRE>&gt; (scientific 7 3)
7000

&gt; (scientific 42 -5)
0.00042
</PRE>

<P>Some versions of Scheme represent fractions in <EM>a</EM>/<EM>b</EM> form, and
some use scientific notation, so you might see <CODE>21/50000</CODE> or <CODE>4.2E-4</CODE>
as the result of the last example instead of <CODE>0.00042</CODE>, but these are
the same value.

<P>(A harder problem for hotshots:  Can you write procedures that go in the
other direction?  So you'd have

<P><PRE>&gt; (sci-coefficient 7000)
7

&gt; (sci-exponent 7000)
3
</PRE>

<P>You might find the primitive procedures <CODE>log</CODE> and <CODE>floor</CODE> helpful.)


<P>
<B>4.9</B>&nbsp;&nbsp;Define a procedure <CODE>discount</CODE> that takes two arguments: an item's
initial price and a percentage discount.  It should return the new price:

<P><PRE>&gt; (discount 10 5)
9.50

&gt; (discount 29.90 50)
14.95
</PRE>

<P>
<B>4.10</B>&nbsp;&nbsp;Write a procedure to compute the tip you should leave at a restaurant.  It
should take the total bill as its argument and return the amount of the
tip.  It should tip by 15%, but it should know to round up so that the
total amount of money you leave (tip plus original bill) is a whole number
of dollars.  (Use the <CODE>ceiling</CODE> procedure to round up.)

<P><PRE>&gt; (tip 19.98)
3.02

&gt; (tip 29.23)
4.77

&gt; (tip 7.54)
1.46
</PRE>

<P>

<HR>
<A NAME="ft1" HREF="defining.html#text1">[1]</A> Technically, the entire
expression <CODE>(define (square x) &hellip)</CODE> is the special form; the word <CODE>define</CODE> itself is called a <EM>keyword</EM>.  But in fact Lispians are
almost always loose about this distinction and say &quot;<CODE>define</CODE> is a
special form,&quot; just as we've done here.  The word &quot;form&quot; is an archaic
synonym for &quot;expression,&quot; so &quot;special form&quot; just means &quot;special
expression.&quot;<P>
<A NAME="ft2" HREF="defining.html#text2">[2]</A> Also, we'll sometimes use the terms &quot;domain&quot; and
&quot;range&quot; when we're talking about procedures, although technically, only
functions have domains and ranges.<P>
<A NAME="ft3" HREF="defining.html#text3">[3]</A> You know, that's
when you wave your hands around in the air instead of explaining what you
mean.<P>
<A NAME="ft4" HREF="defining.html#text4">[4]</A> You may be thinking that this is rather an
inefficient way to do things&mdash;all this copying and replacement before you
can actually compute anything.  Perhaps you're afraid that your Scheme
programs will run very slowly as a result.  Don't worry.  It really
happens in a different way, but the effect is the same except for the
speed.<P>
<A NAME="ft5" HREF="defining.html#text5">[5]</A> Until we started defining our own procedures in this
chapter, all of the little people were hired by Alonzo, because all
expressions were typed directly to a Scheme prompt.  Now expressions can
come from the bodies of procedures, and so the little people needed to
compute those expressions are hired by the little person who's computing
that procedure.  Notice also that each little person <EM>reports to</EM>
another little person, not necessarily the one who <EM>hired</EM> her.  In
this case, if Harry hires Shari for <CODE>sqrt</CODE>, Paul for <CODE>+</CODE>, and Slim
and Sydney for the two <CODE>square</CODE>s, then Slim reports to Paul, not to
Harry.  Only Shari reports directly to Harry.<P>
<A NAME="ft6" HREF="defining.html#text6">[6]</A> This is especially problematic for people
who used to program in a language like Pascal or BASIC, where you say things
like &quot;<CODE>X = X * 3</CODE>&quot; all the time.<P>
<P><A HREF="../ss-toc2.html">(back to Table of Contents)</A><P>
<A HREF="../ssch3/people.html"><STRONG>BACK</STRONG></A>
chapter thread <A HREF="../ssch5/words.html"><STRONG>NEXT</STRONG></A>

<P>
<ADDRESS>
<A HREF="../index.html">Brian Harvey</A>, 
<CODE>bh@cs.berkeley.edu</CODE>
</ADDRESS>
</BODY>
</HTML>