Memory for Functions

No matter how often we use a function with one and the same argument, we always get the same result. Even an accumulator-style function produces the same result every time we apply it to the same argument, as long as the accumulator argument is also the same. Functions simply do not have any memory about their past uses. Many programs, though, must remember something about their past uses. Recall that a program typically consists of several functions. In the past we have always assumed that there is one main function and all others are auxiliary and invisible to the user. In some cases, however, a user may expect more than one service from a program, and each service is best implemented as a function. When a program provides more than one function as a service to the user, it is common that, for sheer convenince or possibly because we add a graphical user interface, the functions must have memory. Because this point is difficult to grasp in the abstract, we study some examples. The first one concerns a program for managing telephone numbers in an address book. The standard address book software provides at east two services:
  1. a service for looking up the phone number of some person; and
  2. a service for adding a name and a phone number to the address book.
Based on our guidelines, the program provides two functions to the user. The user can apply those functions in DrScheme's <#43732#>Interactions<#43732#> window to appropriate data. Or, we can develop a graphical user interface with text fields and buttons so that the user doesn't need to know anything about programming. Figure~#figpbgui#43733> displays such an interface.
rawhtml54 <#43734#>Figure: A phonebook GUI<#43734#>
The two services roughly correspond to two functions:
<#71696#>;; <#67984#><#43740#>lookup<#43740#> <#43741#>:<#43741#> <#43742#>list-of-symbol-number-pairs<#43742#> <#43743#>symbol<#43743#> <#43744#><#43744#><#43745#>-;SPMgt;<#43745#><#43746#><#43746#> <#43747#>number<#43747#> <#43748#>or<#43748#> <#43749#>false<#43749#><#67984#><#71696#>
<#71697#>;; to lookup the number associated with <#67985#><#43750#>name<#43750#><#67985#> in <#67986#><#43751#>pb<#43751#><#67986#><#71697#> 
<#71698#>;; if it doesn't find <#67987#><#43752#>name<#43752#><#67987#>, the function produces <#67988#><#43753#>false<#43753#><#67988#><#71698#> 
<#43754#>(define<#43754#> <#43755#>(lookup<#43755#> <#43756#>pb<#43756#> <#43757#>name)<#43757#> <#43758#>...)<#43758#> 
<#71699#>;; <#67989#><#43759#>add-to-address-book<#43759#> <#43760#>:<#43760#> <#43761#>symbol<#43761#> <#43762#>number<#43762#> <#43763#><#43763#><#43764#>-;SPMgt;<#43764#><#43765#><#43765#> <#43766#>void<#43766#><#67989#><#71699#> 
<#71700#>;; to add <#67990#><#43767#>name<#43767#><#67990#> and <#67991#><#43768#>number<#43768#><#67991#> to <#67992#><#43769#>address-book<#43769#><#67992#><#71700#> 
<#43770#>(define<#43770#> <#43771#>(add-to-address-book<#43771#> <#43772#>name<#43772#> <#43773#>number)<#43773#> <#43774#>...)<#43774#> 
<#43775#>(d<#43775#><#43776#>efine<#43776#> <#43777#>ADDRESS-BOOK<#43777#> 
  <#43778#>(list<#43778#> <#43779#>(list<#43779#> <#43780#>'<#43780#><#43781#>Adam<#43781#> <#43782#>1)<#43782#> 
        <#43783#>(list<#43783#> <#43784#>'<#43784#><#43785#>Eve<#43785#> <#43786#>2)))<#43786#> 
We also introduce a variable definition for maintaing a list of name-number associations. The first function is a variant of our very first recursive function. A user applies it to a list of name-number associations, such as <#67993#><#43790#>ADDRESS-BOOK<#43790#><#67993#>, and a name. It produces a number, if the name is on the list, or <#67994#><#43791#>false<#43791#><#67994#> otherwise. The second function is radically different from what we have seen. The user would apply it to a name and a number and, any future lookup of that name would then produce that number. Let's imagine an interaction in DrScheme:
<#43796#>;SPMgt;<#43796#> <#43797#>(lookup<#43797#> <#43798#>ADDRESS-BOOK<#43798#> <#43799#>'<#43799#><#43800#>Adam)<#43800#>
<#43801#>1<#43801#> 
<#43802#>;SPMgt;<#43802#> <#43803#>(lookup<#43803#> <#43804#>ADDRESS-BOOK<#43804#> <#43805#>'<#43805#><#43806#>Dawn)<#43806#> 
<#43807#>false<#43807#> 
<#43808#>;SPMgt;<#43808#> <#43809#>(add-to-address-book<#43809#> <#43810#>'<#43810#><#43811#>Dawn<#43811#> <#43812#>4)<#43812#> 
<#43813#>;SPMgt;<#43813#> <#43814#>(lookup<#43814#> <#43815#>ADDRESS-BOOK<#43815#> <#43816#>'<#43816#><#43817#>Dawn)<#43817#> 
<#43818#>4<#43818#> 
The first two confirm that <#67995#><#43822#>'<#43822#><#43823#>Adam<#43823#><#67995#> has the phone number <#67996#><#43824#>1<#43824#><#67996#> and that we don't have phone number for <#67997#><#43825#>'<#43825#><#43826#>Dawn<#43826#><#67997#>. The third one adds the phone number <#67998#><#43827#>4<#43827#><#67998#> for <#67999#><#43828#>'<#43828#><#43829#>Dawn<#43829#><#67999#> to <#68000#><#43830#>ADDRESS-BOOK<#43830#><#68000#>. And the last interaction shows that the very same use of <#68001#><#43831#>lookup<#43831#><#68001#> as before now produces the expected phone number. In the past, the only way we could have achieved this same effect is by editing the definition of <#68002#><#43832#>ADDRESS-BOOK<#43832#><#68002#>. But, we do not wish users to edit our programs. Indeed, they shouldn't even have access to our programs. We are therefore forced to provide an interface with a function that permits such changes. We could go even further and implement the graphical interface of figure~#figpbgui#43833>. A dialog equivalent to the above interaction would proceed as follows:
  1. Type <#43835#>Adam<#43835#> into the text field, click the <#43836#>Lookup<#43836#> button, and ``1'' appears in the lower text field.
  2. Enter <#43837#>Dawn<#43837#> into the text field, click the <#43838#>Lookup<#43838#> button, and some message concerning a missing number appears in the lower text field.
  3. Replace the message with ``4'' and click the <#43839#>Add<#43839#> button.
  4. Erase the ``4'' from the lower text field, click the <#43840#>Lookup<#43840#> and the ``4'' shows up again.
In short, providing a convenient interface to a user forces us to develop a program whose functions know about each other's usage history.
rawhtml55 <#43842#>Figure: The three stages of a traffic light canvas and its GUI<#43842#>
The second example, a traffic light simulation, illustrates how a single function may need to have some memory. Recall the function <#68003#><#43844#>next<#43844#><#68003#> from exercise~#extrafficdraw5#43845>. It consumes the current color of a traffic light and, with the help of <#68004#><#43846#>clear-bulb<#43846#><#68004#> and <#68005#><#43847#>draw-bulb<#43847#><#68005#>, switches the state of the traffic light on a canvas to the next traffic color. The result is the next color. A user who wishes to switch the traffic light four times in a row, must enter
<#43852#>(next<#43852#> <#43853#>(next<#43853#> <#43854#>(next<#43854#> <#43855#>(next<#43855#> <#43856#>'<#43856#><#43857#>red))))<#43857#>
into the <#43861#>Interactions<#43861#> window. An even more convenient user interface, however, would provide a button that the user can click. Providing a button means to provide a call-back function that somehow knows about the current state of the traffic light and changes it. Let's call this function <#68006#><#43862#>next<#43862#><#68006#>, too, but let's assume that it consumes no arguments. Here is an imaginary interaction using this function:
<#43867#>;SPMgt;<#43867#> <#43868#>(next)<#43868#>
<#43869#>;SPMgt;<#43869#> <#43870#>(next)<#43870#> 
<#43871#>;SPMgt;<#43871#> <#43872#>(next)<#43872#> 
Every time we apply <#68007#><#43876#>next<#43876#><#68007#> to no arguments, it produces the invisible value and simulates the switch of state in the traffic light on the canvas. In other words, the canvas cycles through the three states depicted in figure~#figtrafficlight#43877>. Equivalently, we can have a user click the ``NEXT'' button three times, which would apply the next function and have the same visual effect. To accomplish this effect, the use of <#68008#><#43878#>next<#43878#><#68008#> must affect its own future uses.
rawhtml56

rawhtml57 <#43879#>Figure: Three stages in the hangman game and its GUI<#43879#>


The final example concerns the <#68009#><#43881#>hangman<#43881#><#68009#> game, which is also the subject of section~#sechangman#43882>. The game program requires us to develop three functions: <#68010#><#43883#>make-word<#43883#><#68010#>, <#68011#><#43884#>reveal<#43884#><#68011#>, and <#68012#><#43885#>draw-next-part<#43885#><#68012#>. We start the game by evaluating
<#43890#>(hangman<#43890#> <#43891#>make-word<#43891#> <#43892#>reveal<#43892#> <#43893#>draw-next-part)<#43893#>
which picks a word, creates the graphical user interface of the lower half of figure~#fighangmanagain#43897>, and draws the leftmost picture in the sequence of the upper half of the figure. The player can then choose a letter from the choice menu in the GUI and click on the ``Check'' button to determine whether the letter occurs in the word. If so, the <#68013#><#43898#>hangman<#43898#><#68013#> function reveals where the letter occurs; if not, it uses our <#68014#><#43899#>draw-next-part<#43899#><#68014#> function to draw the next stage in the hangman picture. The more bad guesses the player makes, the more of the stick figure appears in the picture (see top-half of figure~#fighangmanagain#43900>). Our description suggests that the <#68015#><#43901#>hangman<#43901#><#68015#> function in the teachpack employs a callback function for the ``Check'' button. Let's call this function <#68016#><#43902#>check<#43902#><#68016#>. It consumes the letter and produces <#68017#><#43903#>true<#43903#><#68017#> if the check reveals new knowledge:
<#43908#>;SPMgt;<#43908#> <#43909#>(check<#43909#> <#43910#>'<#43910#><#43911#>b)<#43911#>
<#43912#>true<#43912#> 
If not, because the letter has already been guessed, the function produces <#68018#><#43916#>false<#43916#><#68018#> to indicate that the player didn't gain new knowledge:
<#43921#>;SPMgt;<#43921#> <#43922#>(check<#43922#> <#43923#>'<#43923#><#43924#>b)<#43924#>
<#43925#>false<#43925#> 
In this case, <#68019#><#43929#>check<#43929#><#68019#> also employs <#68020#><#43930#>draw-next-part<#43930#><#68020#> to draw another part of the hangman figure. Of course, to accomplish this, <#68021#><#43931#>hangman<#43931#><#68021#> and <#68022#><#43932#>check<#43932#><#68022#> must have some memory about how often the ``Check'' button was used and how often it was used with a negative result. With our current knowledge of Scheme, we cannot formulate functions such as <#68023#><#43933#>add-to-address-book<#43933#><#68023#>, <#68024#><#43934#>next<#43934#><#68024#>, or <#68025#><#43935#>check<#43935#><#68025#>. To fill this gap in our knowledge, the next section introduces <#68026#><#43936#>set!<#43936#><#68026#> expressions. This new form of expression permits functions to change the value that a <#68027#><#43938#>define<#43938#><#68027#>d variable represents. Using this new construct, we can formulate Scheme functions that have memory. That is, we can define functions that know something about their history and the history of other functions.