Accumulator-Style Functions

When we have decided that an accumulator-style function is necessary, we introduce it in two steps:
Setting-up an accumulator:
First, we must understand what knowledge the accumulator needs to remember about the parameters proper and then how it is to remember it. For example, for the conversion of relative distances to absolute distances, it suffices to accumulate the total distance encountered so far. For the routing problem, we needed the accumulator to remember every node inspected so far. Thus the first accumulator was just a number, the second one a list of nodes. The best way to discuss the accumulation process is to introduce a template of the accumulator-style function via a <#67499#><#40693#>local<#40693#><#67499#> definition and to name the parameters of the function proper differently from those of the auxiliary function. Let's take a look at the <#67500#><#40694#>reverse<#40694#><#67500#> example:
<#71617#>;; <#67501#><#40699#>reverse<#40699#> <#40700#>:<#40700#> <#40701#>(listof<#40701#> <#40702#>X)<#40702#> <#40703#><#40703#><#40704#>-;SPMgt;<#40704#><#40705#><#40705#> <#40706#>(listof<#40706#> <#40707#>X)<#40707#><#67501#><#71617#>
<#71618#>;; to construct the reverse of <#67502#><#40708#>alox<#40708#><#67502#><#71618#> 
<#40709#>(d<#40709#><#40710#>efine<#40710#> <#40711#>(reverse<#40711#> <#40712#>alox0)<#40712#> 
  <#40713#>(l<#40713#><#40714#>ocal<#40714#> <#40715#>(<#40715#><#71619#>;; <#67503#><#40716#>accumulator<#40716#><#67503#> ...<#71619#> 
          <#40717#>(d<#40717#><#40718#>efine<#40718#> <#40719#>(rev<#40719#> <#40720#>alox<#40720#> <#40721#>accumulator)<#40721#>        
            <#40722#>(c<#40722#><#40723#>ond<#40723#> 
              <#40724#>[<#40724#><#40725#>(empty?<#40725#> <#40726#>alox)<#40726#> <#40727#>...]<#40727#> 
              <#40728#>[<#40728#><#40729#>e<#40729#><#40730#>lse<#40730#> 
                <#40731#>...<#40731#> <#40732#>(rev<#40732#> <#40733#>(rest<#40733#> <#40734#>alox)<#40734#> #tex2html_wrap73970#<#40738#>)<#40738#> 
                <#40739#>...<#40739#> <#40740#>]<#40740#><#40741#>)))<#40741#> 
    <#40742#>(rev<#40742#> <#40743#>alox0<#40743#> <#40744#>...)))<#40744#> 
Here we have a definition of <#67505#><#40748#>reverse<#40748#><#67505#> with an auxiliary function <#67506#><#40749#>rev<#40749#><#67506#> in template form. This auxiliary template has one parameter in addition to those of <#67507#><#40750#>reverse<#40750#><#67507#>: the accumulating parameter. The box in the recursive application indicates that we need an expression that maintains the accumulation process and that this process depends on the current value of <#67508#><#40751#>accumulator<#40751#><#67508#> and <#67509#><#40752#>(first<#40752#>\ <#40753#>alox)<#40753#><#67509#>, the value <#67510#><#40754#>rev<#40754#><#67510#> is about to forget. Clearly, <#67511#><#40755#>reverse<#40755#><#67511#> cannot forget anything, because it only reverses the order of items on the list. Hence, we might just wish to accumulate all items that <#67512#><#40756#>rev<#40756#><#67512#> encounters. This means
  1. that <#67513#><#40758#>accumulator<#40758#><#67513#> stands for a list, and
  2. that it stands for all those items in <#67514#><#40759#>alox0<#40759#><#67514#> that precede the <#67515#><#40760#>alox<#40760#><#67515#> argument of <#67516#><#40761#>rev<#40761#><#67516#>.
For the second part of the analysis, it is critical that we can distinguish the original argument, <#67517#><#40763#>alox0<#40763#><#67517#>, from the current one, <#67518#><#40764#>alox<#40764#><#67518#>. Now that we know the rough purpose of the accumulator, let's consider what the first value should be and what we should do for the recursion. When we apply <#67519#><#40765#>rev<#40765#><#67519#> in the body of the <#67520#><#40766#>local<#40766#>-expression<#67520#>, it receives <#67521#><#40767#>alox0<#40767#><#67521#>, which means that it hasn't encountered any of its items. The initial value for <#67522#><#40768#>accumulator<#40768#><#67522#> is <#67523#><#40769#>empty<#40769#><#67523#>. When <#67524#><#40770#>rev<#40770#><#67524#> recurs, it has just encountered one extra item: <#67525#><#40771#>(first<#40771#>\ <#40772#>alox)<#40772#><#67525#>. To remember it, we can <#67526#><#40773#>cons<#40773#><#67526#> it onto the current value of accumulator. Here is the enhanced definition:
<#71620#>;; <#67527#><#40778#>reverse<#40778#> <#40779#>:<#40779#> <#40780#>(listof<#40780#> <#40781#>X)<#40781#> <#40782#><#40782#><#40783#>-;SPMgt;<#40783#><#40784#><#40784#> <#40785#>(listof<#40785#> <#40786#>X)<#40786#><#67527#><#71620#>
<#71621#>;; to construct the reverse of <#67528#><#40787#>alox<#40787#><#67528#><#71621#> 
<#40788#>(d<#40788#><#40789#>efine<#40789#> <#40790#>(reverse<#40790#> <#40791#>alox0)<#40791#> 
  <#40792#>(l<#40792#><#40793#>ocal<#40793#> <#40794#>(<#40794#><#71622#>;; <#67529#><#40795#>accumulator<#40795#><#67529#> is the reversed list of all those items<#71622#> 
          <#71623#>;; on <#67530#><#40796#>alox0<#40796#><#67530#> that precede <#67531#><#40797#>alox<#40797#><#67531#><#71623#> 
          <#40798#>(d<#40798#><#40799#>efine<#40799#> <#40800#>(rev<#40800#> <#40801#>alox<#40801#> <#40802#>accumulator)<#40802#>        
            <#40803#>(c<#40803#><#40804#>ond<#40804#> 
              <#40805#>[<#40805#><#40806#>(empty?<#40806#> <#40807#>alox)<#40807#> <#40808#>...]<#40808#> 
              <#40809#>[<#40809#><#40810#>e<#40810#><#40811#>lse<#40811#> 
                <#40812#>...<#40812#> <#40813#>(rev<#40813#> <#40814#>(rest<#40814#> <#40815#>alox)<#40815#> <#40816#>(cons<#40816#> <#40817#>(first<#40817#> <#40818#>alox)<#40818#> <#40819#>accumulator))<#40819#> 
                <#40820#>...]<#40820#><#40821#>)))<#40821#> 
    <#40822#>(rev<#40822#> <#40823#>alox0<#40823#> <#40824#>empty)))<#40824#> 
A close inspection reveals that <#67532#><#40828#>accumulator<#40828#><#67532#> is not just the items on <#67533#><#40829#>alox0<#40829#><#67533#> that precede but a list of these items in reverse order.
Exploiting an accumulator:
Once we have decided on what knowledge the accumulator maintains and how it is maintained, we can move to the question of how to exploit this knowledge for our function. In the case of <#67534#><#40830#>reverse<#40830#><#67534#>, the answer is almost obvious. If <#67535#><#40831#>accumulator<#40831#><#67535#> is the list of all items on <#67536#><#40832#>alox0<#40832#><#67536#> that precede <#67537#><#40833#>alox<#40833#><#67537#> in reverse order, then, if <#67538#><#40834#>alox<#40834#><#67538#> is empty, <#67539#><#40835#>accumulator<#40835#><#67539#> stands for the reverse of <#67540#><#40836#>alox0<#40836#><#67540#>. Put differently: if <#67541#><#40837#>alox<#40837#><#67541#> is <#67542#><#40838#>empty<#40838#><#67542#>, <#67543#><#40839#>rev<#40839#><#67543#>'s answer is <#67544#><#40840#>accumulator<#40840#><#67544#>, and that is the answer we want in both cases:
<#71624#>;; <#67545#><#40845#>reverse<#40845#> <#40846#>:<#40846#> <#40847#>(listof<#40847#> <#40848#>X)<#40848#> <#40849#><#40849#><#40850#>-;SPMgt;<#40850#><#40851#><#40851#> <#40852#>(listof<#40852#> <#40853#>X)<#40853#><#67545#><#71624#>
<#71625#>;; to construct the reverse of <#67546#><#40854#>alox<#40854#><#67546#><#71625#> 
<#40855#>(d<#40855#><#40856#>efine<#40856#> <#40857#>(reverse<#40857#> <#40858#>alox0)<#40858#> 
  <#40859#>(l<#40859#><#40860#>ocal<#40860#> <#40861#>(<#40861#><#71626#>;; <#67547#><#40862#>accumulator<#40862#><#67547#> is the reversed list of all those items<#71626#> 
          <#71627#>;; on <#67548#><#40863#>alox0<#40863#><#67548#> that precede <#67549#><#40864#>alox<#40864#><#67549#><#71627#> 
          <#40865#>(d<#40865#><#40866#>efine<#40866#> <#40867#>(rev<#40867#> <#40868#>alox<#40868#> <#40869#>accumulator)<#40869#>        
            <#40870#>(c<#40870#><#40871#>ond<#40871#> 
              <#40872#>[<#40872#><#40873#>(empty?<#40873#> <#40874#>alox)<#40874#> <#40875#>accumulator]<#40875#> 
              <#40876#>[<#40876#><#40877#>e<#40877#><#40878#>lse<#40878#> 
                <#40879#>(rev<#40879#> <#40880#>(rest<#40880#> <#40881#>alox)<#40881#> <#40882#>(cons<#40882#> <#40883#>(first<#40883#> <#40884#>alox)<#40884#> <#40885#>accumulator))]<#40885#><#40886#>)))<#40886#> 
    <#40887#>(rev<#40887#> <#40888#>alox0<#40888#> <#40889#>empty)))<#40889#> 
The key step of this development was the precise description of the role of <#67550#><#40894#>accumulator<#40894#><#67550#>. In general, an <#67551#><#40895#>ACCUMULATOR INVARIANT<#40895#><#67551#> describes a relationship between the argument proper of the function, the current argument of the auxiliary function, and the accumulator that must always hold when an accumulator-style function is used.