State Changes from Recursion

Functions that affect the memory of a program may not only process simple forms of data but also arbitrarily large pieces of data. To understand how this works, let us take a closer look at the purpose of <#68613#><#47493#>reveal-list<#47493#><#68613#> from the hangman game program. As we have just seen, the function compares <#68614#><#47494#>guess<#47494#><#68614#> with each letter in <#68615#><#47495#>chosen-word<#47495#><#68615#>. If it is the same, <#68616#><#47496#>guess<#47496#><#68616#> may uncover new knowledge and is included at the appropriate position in the word; otherwise, the corresponding letter from <#68617#><#47497#>status-word<#47497#><#68617#> represents what the player knows. The <#68618#><#47498#>hangman-guess<#47498#><#68618#> function then compares the result of <#68619#><#47499#>reveal-list<#47499#><#68619#> with the old value of <#68620#><#47500#>status-word<#47500#><#68620#> to find out whether the player uncovered new knowledge. Furthermore, the result is compared with <#68621#><#47501#>chosen-word<#47501#><#68621#> again if the player found new knowledge, because <#68622#><#47502#>guess<#47502#><#68622#> might have matched all remaining unknown letters. Clearly, both of these comparisons repeat the computations of <#68623#><#47503#>reveal-one<#47503#><#68623#>. The problem is that the result of <#68624#><#47504#>reveal-one<#47504#><#68624#> is useful to <#68625#><#47505#>reveal-list<#47505#><#68625#> and that the result of its individual comparisons are useful in the conditionals of <#68626#><#47506#>hangman-guess<#47506#><#68626#>. We can solve the first part of the problem with the use of an additional piece of memory: a state variable that records whether <#68627#><#47507#>reveal-one<#47507#><#68627#> uncovers a letter. The state variable, let's call it <#68628#><#47508#>new-knowledge<#47508#><#68628#>, is modified by <#68629#><#47509#>reveal-one<#47509#><#68629#> if it determines that <#68630#><#47510#>guess<#47510#><#68630#> uncovers a currently hidden letter in <#68631#><#47511#>chosen-word<#47511#><#68631#>. The <#68632#><#47512#>hangman-guess<#47512#><#68632#> function can use <#68633#><#47513#>new-knowledge<#47513#><#68633#> to find out what <#68634#><#47514#>reveal-one<#47514#><#68634#> discovered. Let us now translate our idea into new program definitions systematically. First, we need to specify the state variable and its meaning:
<#71799#>;; <#68635#><#47519#>new-knowledge<#47519#> <#47520#>:<#47520#> <#47521#>boolean<#47521#><#68635#><#71799#>
<#47522#>;; the variable represents whether the most recent application of<#47522#> 
<#71800#>;; <#68636#><#47523#>reveal-list<#47523#><#68636#> has provided the player with new knowledge<#71800#> 
<#47524#>(define<#47524#> <#47525#>new-knowledge<#47525#> <#47526#>false)<#47526#> 
Second, we must consider what it means to initialize the new state variable. From what we know, the state variable is used every time <#68637#><#47530#>reveal-list<#47530#><#68637#> is applied to <#68638#><#47531#>guess<#47531#><#68638#>. When the application starts, the state variable should be <#68639#><#47532#>false<#47532#><#68639#>; it should change to <#68640#><#47533#>true<#47533#><#68640#> if <#68641#><#47534#>guess<#47534#><#68641#> is useful. This suggests that <#68642#><#47535#>new-knowledge<#47535#><#68642#> is to be initialized to <#68643#><#47536#>false<#47536#><#68643#> every time <#68644#><#47537#>reveal-list<#47537#><#68644#> is applied. We can achieve this re-initialization by changing <#68645#><#47538#>reveal-list<#47538#><#68645#> so that it sets the state variable before it computes anything else:
<#71801#>;; <#68646#><#47543#>reveal-list<#47543#> <#47544#>:<#47544#> <#47545#>word<#47545#> <#47546#>word<#47546#> <#47547#>letter<#47547#> <#47548#><#47548#><#47549#>-;SPMgt;<#47549#><#47550#><#47550#> <#47551#>word<#47551#><#68646#><#71801#>
<#47552#>;; to compute the new status word<#47552#> 
<#71802#>;; effect: to set <#68647#><#47553#>new-knowledge<#47553#><#68647#> to <#68648#><#47554#>false<#47554#><#68648#> first<#71802#> 
<#47555#>(d<#47555#><#47556#>efine<#47556#> <#47557#>(reveal-list<#47557#> <#47558#>chosen-word<#47558#> <#47559#>status-word<#47559#> <#47560#>guess)<#47560#> 
  <#47561#>(l<#47561#><#47562#>ocal<#47562#> <#47563#>((define<#47563#> <#47564#>(reveal-one<#47564#> <#47565#>chosen-letter<#47565#> <#47566#>status-letter)<#47566#> <#47567#>...))<#47567#> 
    <#47568#>(b<#47568#><#47569#>egin<#47569#> 
      <#72348#>#tex2html_wrap_inline74096#<#72348#> 
      <#47573#>(map<#47573#> <#47574#>reveal-one<#47574#> <#47575#>chosen-word<#47575#> <#47576#>status-word))))<#47576#> 
The underlined expression is the essential modification. The <#68650#><#47580#>local<#47580#><#68650#> expression defines the auxiliary function <#68651#><#47581#>reveal-one<#47581#><#68651#> and then evaluates the <#68652#><#47582#>local<#47582#><#68652#>'s body. The first step of the body is to initialize <#68653#><#47583#>new-knowledge<#47583#><#68653#>. Third, we must develop the program that modifies <#68654#><#47584#>new-knowledge<#47584#><#68654#>. Here the program already exists: <#68655#><#47585#>reveal-list<#47585#><#68655#>, so our task is to modify it in such a way that it changes the state variable appropriately. Let's describe the idea with a modified effect statement:
<#71804#>;; <#68656#><#47590#>reveal-list<#47590#> <#47591#>:<#47591#> <#47592#>word<#47592#> <#47593#>word<#47593#> <#47594#>letter<#47594#> <#47595#><#47595#><#47596#>-;SPMgt;<#47596#><#47597#><#47597#> <#47598#>word<#47598#><#68656#><#71804#>
<#47599#>;; to compute the new status word<#47599#> 
<#47600#>;; effect: <#47600#> 
<#71805#>;; (1) to set <#68657#><#47601#>new-knowledge<#47601#><#68657#> to <#68658#><#47602#>false<#47602#><#68658#> first<#71805#> 
<#71806#>;; (2) to set <#68659#><#47603#>new-knowledge<#47603#><#68659#> to <#68660#><#47604#>true<#47604#><#68660#> if <#68661#><#47605#>guess<#47605#><#68661#> reveals new knowledge<#71806#> 
The first part of the effect is necessary for the second one; an experienced programmer may drop it. Next we should modify the examples for the function to illustrate what kind of effects happen. The purpose of the function is to compute the new status word by checking whether <#68662#><#47609#>guess<#47609#><#68662#> occurs in the <#68663#><#47610#>chosen-word<#47610#><#68663#>. There are two basic situations depending on whether <#68664#><#47611#>guess<#47611#><#68664#> reveals new knowledge or not:
  1. If <#68665#><#47613#>status-word<#47613#><#68665#> is <#68666#><#47614#>(list<#47614#>\ <#47615#>'<#47615#><#47616#>b<#47616#>\ <#47617#>'<#47617#><#47618#>_<#47618#>\ <#47619#>'<#47619#><#47620#>l<#47620#>\ <#47621#>'<#47621#><#47622#>l)<#47622#><#68666#> and <#68667#><#47623#>chosen-word<#47623#><#68667#> is <#68668#><#47624#>(list<#47624#>\ <#47625#>'<#47625#><#47626#>b<#47626#>\ <#47627#>'<#47627#><#47628#>a<#47628#>\ <#47629#>'<#47629#><#47630#>l<#47630#>\ <#47631#>'<#47631#><#47632#>l)<#47632#><#68668#>, then evaluating
    <#47637#>(reveal-one<#47637#> <#47638#>chosen-wor<#47638#> <#47639#>status-word<#47639#> <#47640#>'<#47640#><#47641#>a)<#47641#>
    
    produces <#68669#><#47645#>(list<#47645#>\ <#47646#>'<#47646#><#47647#>b<#47647#>\ <#47648#>'<#47648#><#47649#>a<#47649#>\ <#47650#>'<#47650#><#47651#>l<#47651#>\ <#47652#>'<#47652#><#47653#>l)<#47653#><#68669#> and <#68670#><#47654#>new-knowledge<#47654#><#68670#> is <#68671#><#47655#>true<#47655#><#68671#>.
  2. If <#68672#><#47656#>status-word<#47656#><#68672#> is <#68673#><#47657#>(list<#47657#>\ <#47658#>'<#47658#><#47659#>b<#47659#>\ <#47660#>'<#47660#><#47661#>_<#47661#>\ <#47662#>'<#47662#><#47663#>_<#47663#>\ <#47664#>'<#47664#><#47665#>_<#47665#><#47666#>)<#47666#><#68673#> and <#68674#><#47667#>chosen-word<#47667#><#68674#> is <#68675#><#47668#>(list<#47668#>\ <#47669#>'<#47669#><#47670#>b<#47670#>\ <#47671#>'<#47671#><#47672#>a<#47672#>\ <#47673#>'<#47673#><#47674#>l<#47674#>\ <#47675#>'<#47675#><#47676#>l)<#47676#><#68675#>, then evaluating
    <#47681#>(reveal-one<#47681#> <#47682#>chosen-wor<#47682#> <#47683#>status-word<#47683#> <#47684#>'<#47684#><#47685#>x)<#47685#>
    
    produces <#68676#><#47689#>(list<#47689#>\ <#47690#>'<#47690#><#47691#>b<#47691#>\ <#47692#>'<#47692#><#47693#>_<#47693#>\ <#47694#>'<#47694#><#47695#>_<#47695#>\ <#47696#>'<#47696#><#47697#>_<#47697#><#47698#>)<#47698#><#68676#> and <#68677#><#47699#>new-knowledge<#47699#><#68677#> is <#68678#><#47700#>false<#47700#><#68678#>.
  3. If <#68679#><#47701#>status-word<#47701#><#68679#> is <#68680#><#47702#>(list<#47702#>\ <#47703#>'<#47703#><#47704#>b<#47704#>\ <#47705#>'<#47705#><#47706#>_<#47706#>\ <#47707#>'<#47707#><#47708#>_<#47708#>\ <#47709#>'<#47709#><#47710#>_<#47710#><#47711#>)<#47711#><#68680#> and <#68681#><#47712#>chosen-word<#47712#><#68681#> is <#68682#><#47713#>(list<#47713#>\ <#47714#>'<#47714#><#47715#>b<#47715#>\ <#47716#>'<#47716#><#47717#>a<#47717#>\ <#47718#>'<#47718#><#47719#>l<#47719#>\ <#47720#>'<#47720#><#47721#>l)<#47721#><#68682#>, then evaluating
    <#47726#>(reveal-one<#47726#> <#47727#>chosen-wor<#47727#> <#47728#>status-word<#47728#> <#47729#>'<#47729#><#47730#>l)<#47730#>
    
    produces <#68683#><#47734#>(list<#47734#>\ <#47735#>'<#47735#><#47736#>b<#47736#>\ <#47737#>'<#47737#><#47738#>_<#47738#>\ <#47739#>'<#47739#><#47740#>l<#47740#>\ <#47741#>'<#47741#><#47742#>l)<#47742#><#68683#> and <#68684#><#47743#>new-knowledge<#47743#><#68684#> is <#68685#><#47744#>true<#47744#><#68685#>.
  4. Finally, if <#68686#><#47745#>status-word<#47745#><#68686#> is <#68687#><#47746#>(list<#47746#>\ <#47747#>'<#47747#><#47748#>b<#47748#>\ <#47749#>'<#47749#><#47750#>_<#47750#>\ <#47751#>'<#47751#><#47752#>l<#47752#>\ <#47753#>'<#47753#><#47754#>l)<#47754#><#68687#> and <#68688#><#47755#>chosen-word<#47755#><#68688#> is <#68689#><#47756#>(list<#47756#>\ <#47757#>'<#47757#><#47758#>b<#47758#>\ <#47759#>'<#47759#><#47760#>a<#47760#>\ <#47761#>'<#47761#><#47762#>l<#47762#>\ <#47763#>'<#47763#><#47764#>l)<#47764#><#68689#>, then evaluating
    <#47769#>(reveal-one<#47769#> <#47770#>chosen-wor<#47770#> <#47771#>status-word<#47771#> <#47772#>'<#47772#><#47773#>l)<#47773#>
    
    produces <#68690#><#47777#>(list<#47777#>\ <#47778#>'<#47778#><#47779#>b<#47779#>\ <#47780#>'<#47780#><#47781#>_<#47781#>\ <#47782#>'<#47782#><#47783#>l<#47783#>\ <#47784#>'<#47784#><#47785#>l)<#47785#><#68690#> and <#68691#><#47786#>new-knowledge<#47786#><#68691#> is <#68692#><#47787#>false<#47787#><#68692#>.
The first two examples cover the basic situations; the third one shows that if <#68693#><#47789#>guess<#47789#><#68693#> reveals several new positions in the word, <#68694#><#47790#>new-knowledge<#47790#><#68694#> also becomes <#68695#><#47791#>true<#47791#><#68695#>; and the last shows how guessing a letter that has been uncovered before means no new knowledge has been added. Given that we already have a function, we can skip the template step and instead focus on the question what we need to change in the existing function. The given version of <#68696#><#47792#>reveal-list<#47792#><#68696#> maps <#68697#><#47793#>reveal-one<#47793#><#68697#> over the two words, which are lists of letters. It is <#68698#><#47794#>reveal-one<#47794#><#68698#> that compares <#68699#><#47795#>guess<#47795#><#68699#> with the letters in <#68700#><#47796#>chosen-word<#47796#><#68700#> and that determines whether the player has uncovered new knowledge. Hence, we must modify the auxiliary function so that it recognizes when <#68701#><#47797#>guess<#47797#><#68701#> represents new knowledge and to set <#68702#><#47798#>new-knowledge<#47798#><#68702#> to true in that case. As it is currently defined, <#68703#><#47799#>reveal-one<#47799#><#68703#> merely compares <#68704#><#47800#>guess<#47800#><#68704#> with the letters in <#68705#><#47801#>chosen-word<#47801#><#68705#>. It does not check whether the player discovers truly new knowledge if <#68706#><#47802#>guess<#47802#><#68706#> and <#68707#><#47803#>chosen-letter<#47803#><#68707#> are the same. The letter <#68708#><#47804#>guess<#47804#><#68708#>, however, represents new knowledge only if the matching letter in the <#47805#>status<#47805#> word is still <#68709#><#47806#>'<#47806#><#47807#>_<#47807#><#68709#>. This suggests the following two modifications:
<#71807#>;; <#68710#><#47812#>reveal-list<#47812#> <#47813#>:<#47813#> <#47814#>word<#47814#> <#47815#>word<#47815#> <#47816#>letter<#47816#> <#47817#><#47817#><#47818#>-;SPMgt;<#47818#><#47819#><#47819#> <#47820#>word<#47820#><#68710#><#71807#>
<#47821#>;; to compute the new status word<#47821#> 
<#71808#>;; effect: to set <#68711#><#47822#>new-knowledge<#47822#><#68711#> to <#68712#><#47823#>true<#47823#><#68712#> if <#68713#><#47824#>guess<#47824#><#68713#> reveals new knowledge<#71808#> 
<#47825#>(d<#47825#><#47826#>efine<#47826#> <#47827#>(reveal-list<#47827#> <#47828#>chosen-word<#47828#> <#47829#>status-word<#47829#> <#47830#>guess)<#47830#> 
  <#47831#>(l<#47831#><#47832#>ocal<#47832#> <#47833#>((d<#47833#><#47834#>efine<#47834#> <#47835#>(reveal-one<#47835#> <#47836#>chosen-letter<#47836#> <#47837#>status-letter)<#47837#> 
            <#47838#>(c<#47838#><#47839#>ond<#47839#> 
              <#47840#>[<#47840#><#47841#>(and<#47841#> <#47842#>(symbol=?<#47842#> <#47843#>chosen-letter<#47843#> <#47844#>guess)<#47844#> 
                    <#72349#>#tex2html_wrap_inline74098#<#72349#><#47850#>)<#47850#> 
               <#47851#>(b<#47851#><#47852#>egin<#47852#> 
                 <#72350#>#tex2html_wrap_inline74100#<#72350#> 
                 <#47856#>guess)]<#47856#> 
              <#47857#>[<#47857#><#47858#>else<#47858#> <#47859#>status-letter]<#47859#><#47860#>)))<#47860#> 
    <#47861#>(b<#47861#><#47862#>egin<#47862#> 
      <#47863#>(set!<#47863#> <#47864#>new-knowledge<#47864#> <#47865#>false)<#47865#> 
      <#47866#>(map<#47866#> <#47867#>reveal-one<#47867#> <#47868#>chosen-word<#47868#> <#47869#>status-word))))<#47869#> 
That is, <#68716#><#47873#>reveal-one<#47873#><#68716#> changes the value of <#68717#><#47874#>new-knowledge<#47874#><#68717#> if, and only if, both <#68718#><#47875#>(symbol=?<#47875#>\ <#47876#>chosen-letter<#47876#>\ <#47877#>guess)<#47877#><#68718#> and <#68719#><#47878#>(symbol=?<#47878#><#47879#> <#47879#><#47880#>status-letter<#47880#>\ <#47881#>'<#47881#><#47882#>_<#47882#><#47883#>)<#47883#><#68719#> are true. In summary, we can use state variables if we wish to communicate several results from one computation to distant places. For such cases, the interface of a function is under our control but we choose to design it such that the function has both a result and an effect. The proper way to achieve these combinations is to develop the computations separately and to merge them later, if necessary.
<#47886#>Exercise 37.3.1<#47886#> Draw a diagram that shows how <#68720#><#47888#>hangman<#47888#><#68720#>, <#68721#><#47889#>hangman-guess<#47889#><#68721#>, and <#68722#><#47890#>reveal-list<#47890#><#68722#> interact with the state variables.~ external Solution<#68723#><#68723#> <#47896#>Exercise 37.3.2<#47896#> Turn the three examples into tests, that is, boolean-valued expressions, and test the new version of <#68724#><#47898#>reveal-list<#47898#><#68724#>. How many times does <#68725#><#47899#>reveal-one<#47899#><#68725#> modify <#68726#><#47900#>new-knowledge<#47900#><#68726#> for the third test case?~ external Solution<#68727#><#68727#> <#47906#>Exercise 37.3.3<#47906#> Modify <#68728#><#47908#>hangman-guess<#47908#><#68728#> in the hangman program to take advantage of the additional information that <#68729#><#47909#>reveal-list<#47909#><#68729#> provides through <#68730#><#47910#>new-knowledge<#47910#><#68730#>.~ external Solution<#68731#><#68731#> <#47916#>Exercise 37.3.4<#47916#> Modify the hangman program a second time to eliminate the second <#68732#><#47918#>equal?<#47918#><#68732#> in <#68733#><#47919#>hangman-guess<#47919#><#68733#>. <#47920#>Hint:<#47920#> \ Introduce a state variable that counts how many letters the player doesn't know yet.~ external Solution<#68734#><#68734#>
Let us study a second example of a function that consumes an arbitrarily large piece of data and modifies the program's memory. The example is a natural extension of the traffic light simulator in section~#secdesignmemory#47928>. We developed two functions:
<#71811#>;; <#68735#><#47933#>init-traffic-light<#47933#> <#47934#>:<#47934#> <#47935#><#47935#><#47936#>-;SPMgt;<#47936#><#47937#><#47937#> <#47938#>void<#47938#><#68735#> <#71811#>
<#71812#>;; effects: (1) to initialize <#68736#><#47939#>current-color<#47939#><#68736#>; (2) to draw traffic light<#71812#> 
and
<#71813#>;; <#68737#><#47947#>next<#47947#> <#47948#>:<#47948#> <#47949#><#47949#><#47950#>-;SPMgt;<#47950#><#47951#><#47951#> <#47952#>void<#47952#><#68737#><#71813#>
<#71814#>;; <#47953#>effects<#47953#>: (1) to change <#68738#><#47954#>current-color<#47954#><#68738#> from <#68739#><#47955#>'<#47955#><#47956#>green<#47956#><#68739#> to <#68740#><#47957#>'<#47957#><#47958#>yellow<#47958#><#68740#>, <#71814#> 
<#71815#>;; <#68741#><#47959#>'<#47959#><#47960#>yellow<#47960#><#68741#> to <#68742#><#47961#>'<#47961#><#47962#>red<#47962#><#68742#>, and <#68743#><#47963#>'<#47963#><#47964#>red<#47964#><#68743#> to <#68744#><#47965#>'<#47965#><#47966#>green<#47966#><#68744#><#71815#> 
<#47967#>;; (2) to re-draw the traffic light appropriately <#47967#> 
The first one starts the process; with the second one, we can repeatedly switch the state of the light by evaluating <#68745#><#47971#>(next)<#47971#><#68745#> in the <#47972#>Interactions<#47972#> window. Typing in <#68746#><#47973#>(next)<#47973#><#68746#> over and over again is tiring, so it is natural to wonder how to write a program that switches the state of the traffic light a 100 or 1000 or 10000 times. In other words, we should develop a program---let's call it <#68747#><#47974#>switch<#47974#><#68747#>---that consumes a natural number and that switches the light from one color to another that many times. The function consumes a natural number and produces <#68748#><#47975#>(<#47975#><#47976#>void<#47976#><#47977#>)<#47977#><#68748#>, after it succeeded in switching the traffic light a sufficient number of times. By now we can immediately write down all the basics, including the template, for a function that consumes a natural number:
<#71816#>;; <#68749#><#47982#>switch<#47982#> <#47983#>:<#47983#> <#47984#>N<#47984#> <#47985#><#47985#><#47986#>-;SPMgt;<#47986#><#47987#><#47987#> <#47988#>void<#47988#><#68749#><#71816#>
<#47989#>;; purpose: it computes nothing of interest<#47989#> 
<#71817#>;; effect: switch the traffic light <#68750#><#47990#>n<#47990#><#68750#> times, <#71817#> 
<#47991#>;; holding each color for three seconds<#47991#> 
<#47992#>(d<#47992#><#47993#>efine<#47993#> <#47994#>(switch<#47994#> <#47995#>n)<#47995#> 
  <#47996#>(c<#47996#><#47997#>ond<#47997#> 
    <#47998#>[<#47998#><#47999#>(zero?<#47999#> <#48000#>n)<#48000#> <#48001#>...]<#48001#> 
    <#48002#>[<#48002#><#48003#>else<#48003#> <#48004#>...<#48004#> <#48005#>(switch<#48005#> <#48006#>(-<#48006#> <#48007#>n<#48007#> <#48008#>1))<#48008#> <#48009#>...]<#48009#><#48010#>))<#48010#> 
The template is that of a conventional, structurally recursive function. Making up an example is also straightforward. If we evaluate <#68751#><#48014#>(switch<#48014#><#48015#> <#48015#><#48016#>4)<#48016#><#68751#>, we wish to see a change from <#68752#><#48017#>'<#48017#><#48018#>red<#48018#><#68752#> to <#68753#><#48019#>'<#48019#><#48020#>yellow<#48020#><#68753#>, <#68754#><#48021#>'<#48021#><#48022#>green<#48022#><#68754#>, and <#68755#><#48023#>'<#48023#><#48024#>red<#48024#><#68755#> again, with each stage visible for three seconds. Defining the full function based on the template is straightforward. We proceed by cases. If <#68756#><#48025#>n<#48025#><#68756#> is <#68757#><#48026#>0<#48026#><#68757#>, the answer is <#68758#><#48027#>(<#48027#><#48028#>void<#48028#><#48029#>)<#48029#><#68758#>. Otherwise, we know that
<#48034#>(switch<#48034#> <#48035#>(-<#48035#> <#48036#>n<#48036#> <#48037#>1))<#48037#>
simulates all the necessary switching actions but one. To accomplish this one additional switch, the function must use <#68759#><#48041#>(next)<#48041#><#68759#> to perform all the state changes and the change of canvas and must wait three seconds. If we put everything together in a <#68760#><#48042#>begin<#48042#>-expression<#68760#>, things happen in the right order:
<#48047#>(begin<#48047#> <#48048#>(sleep-for-a-while<#48048#> <#48049#>3)<#48049#>
       <#48050#>(next)<#48050#> 
       <#48051#>(switch<#48051#> <#48052#>(-<#48052#> <#48053#>n<#48053#> <#48054#>1)))<#48054#> 
The top of figure~#figswitching#48058> is the complete definition for <#68761#><#48059#>switch<#48059#><#68761#>.
<#71818#>;; <#68762#><#48064#>switch<#48064#> <#48065#>:<#48065#> <#48066#>N<#48066#> <#48067#><#48067#><#48068#>-;SPMgt;<#48068#><#48069#><#48069#> <#48070#>void<#48070#><#68762#><#71818#>
<#71819#>;; effect: switch the traffic light <#68763#><#48071#>n<#48071#><#68763#> times, holding each color for <#68764#><#48072#>3<#48072#><#68764#> seconds<#71819#> 
<#48073#>;; structural recursion <#48073#> 
<#48074#>(d<#48074#><#48075#>efine<#48075#> <#48076#>(switch<#48076#> <#48077#>n)<#48077#> 
  <#48078#>(c<#48078#><#48079#>ond<#48079#> 
    <#48080#>[<#48080#><#48081#>(=<#48081#> <#48082#>n<#48082#> <#48083#>0)<#48083#> <#48084#>(<#48084#><#48085#>void<#48085#><#48086#>)]<#48086#> 
    <#48087#>[<#48087#><#48088#>else<#48088#> <#48089#>(begin<#48089#> <#48090#>(sleep-for-a-while<#48090#> <#48091#>3)<#48091#> 
                 <#48092#>(next)<#48092#> 
                 <#48093#>(switch<#48093#> <#48094#>(-<#48094#> <#48095#>n<#48095#> <#48096#>1)))]<#48096#><#48097#>))<#48097#> 
<#71820#>;; <#68765#><#48105#>switch-forever<#48105#> <#48106#>:<#48106#> <#48107#><#48107#><#48108#>-;SPMgt;<#48108#><#48109#><#48109#> <#48110#>void<#48110#><#68765#><#71820#>
<#71821#>;; effect: switch the traffic light forever, holding each color for <#68766#><#48111#>3<#48111#><#68766#> seconds<#71821#> 
<#48112#>;; generative recursion <#48112#> 
<#48113#>(d<#48113#><#48114#>efine<#48114#> <#48115#>(switch-forever)<#48115#> 
  <#48116#>(begin<#48116#> <#48117#>(sleep-for-a-while<#48117#> <#48118#>3)<#48118#> 
         <#48119#>(next)<#48119#> 
         <#48120#>(switch-forever)))<#48120#> 
<#48124#>Figure: Two ways of switching traffic lights<#48124#>
An alternative is to switch the traffic light forever or at least until it breaks due to some external event. In this case, the simulator does not consume any argument and, when applied, runs forever. This is the simplest form of generative recursion we can possibly encounter:
<#71822#>;; <#68767#><#48130#>switch-forever<#48130#> <#48131#>:<#48131#> <#48132#><#48132#><#48133#>-;SPMgt;<#48133#><#48134#><#48134#> <#48135#>void<#48135#><#68767#><#71822#>
<#48136#>;; effect: switch the traffic light forever, <#48136#> 
<#71823#>;; holding each color for <#68768#><#48137#>3<#48137#><#68768#> seconds<#71823#> 
<#48138#>(d<#48138#><#48139#>efine<#48139#> <#48140#>(switch-forever)<#48140#> 
  <#48141#>...<#48141#> 
  <#48142#>(switch-forever))<#48142#> 
Because the program does not terminate under any conditions, the template contains only one recursive call. This suffices to construct an eternally looping function. Using this template, we can define the complete function as before. Before recurring, the function must sleep and switch the light with <#68769#><#48146#>next<#48146#><#68769#>. We can accomplish this with a <#68770#><#48147#>begin<#48147#>-expression<#68770#>, as shown in the bottom definition of figure~#figswitching#48148>. In summary, when we must develop recursive functions that modify the program's memory, we choose the design recipe that best matches our situation and proceed accordingly. In particular, if the function has both an interesting purpose and an effect, as for example <#68771#><#48149#>reveal-list<#48149#><#68771#>, we should first develop the pure function and then add the effects later.
<#48152#>Exercise 37.3.5<#48152#> In section~#seclossgenerative#48154>, we discussed how to search for routes in simple graphs. The Scheme representation of a simple graph is a list of pairs (of symbols). The pairs specify the direct connections among the nodes in the graph. Each node is the beginning of exactly one connection, but may be the end of several such connections or none. Given two nodes in a simple graph, the problem is to find out whether one can go from the first to the second. Recall is our first attempt at a function that determines whether the route exists (see also figure~#figrouteexists1#48155>):
<#71824#>;; <#68772#><#48160#>route-exists?<#48160#> <#48161#>:<#48161#> <#48162#>node<#48162#> <#48163#>node<#48163#> <#48164#>simple-graph<#48164#> <#48165#><#48165#><#48166#>-;SPMgt;<#48166#><#48167#><#48167#> <#48168#>boolean<#48168#><#68772#><#71824#>
<#71825#>;; to determine whether there is a route from <#68773#><#48169#>orig<#48169#><#68773#> to <#68774#><#48170#>dest<#48170#><#68774#> in <#68775#><#48171#>sg<#48171#><#68775#><#71825#> 
<#48172#>;; generative recursion <#48172#> 
<#48173#>(d<#48173#><#48174#>efine<#48174#> <#48175#>(route-exists?<#48175#> <#48176#>orig<#48176#> <#48177#>dest<#48177#> <#48178#>sg)<#48178#> 
  <#48179#>(c<#48179#><#48180#>ond<#48180#> 
    <#48181#>[<#48181#><#48182#>(symbol=?<#48182#> <#48183#>orig<#48183#> <#48184#>dest)<#48184#> <#48185#>true<#48185#><#48186#>]<#48186#> 
    <#48187#>[<#48187#><#48188#>else<#48188#> <#48189#>(route-exists?<#48189#> <#48190#>(neighbor<#48190#> <#48191#>orig<#48191#> <#48192#>sg)<#48192#> <#48193#>dest<#48193#> <#48194#>sg)]<#48194#><#48195#>))<#48195#> 
The function checks whether the origination and destination nodes are the same. If not, it generates a new problem by looking up the neighbor of the origination node in the graph. On occasion, <#68776#><#48199#>route-exists?<#48199#><#68776#> fails to produce an answer if the graph contains a cycle. In section~#seclossgenerative#48200> we solved the problem with an accumulator. It is also possible to solve it with a state variable that keeps track of the origination nodes that <#68777#><#48201#>route-exists?<#48201#><#68777#> has visited for one particular attempt. Modify the function appropriately.~ external Solution<#68778#><#68778#> <#48207#>Exercise 37.3.6<#48207#> In section~#secfilesmodels#48209>, we developed several simple models of a computer's file system. Develop the function <#68779#><#48210#>dir-listing<#48210#><#68779#>, which consumes a directory and produces a list of all file names in the directory and all of its subdirectories. The function also sets the state variable <#68780#><#48211#>how-many-directories<#48211#><#68780#> to the number of subdirectories it encounters during the process.~ external Solution<#68781#><#68781#>