Structural versus Generative Recursion

The template for algorithms is so general that it even covers functions based on structural recursion. Consider the version with one termination clause and one generation step:
<#33956#>(d<#33956#><#33957#>efine<#33957#> <#33958#>(generative-recursive-fun<#33958#> <#33959#>problem)<#33959#>
  <#33960#>(c<#33960#><#33961#>ond<#33961#> 
    <#33962#>[<#33962#><#33963#>(trivially-solvable?<#33963#> <#33964#>problem)<#33964#> 
     <#33965#>(determine-solution<#33965#> <#33966#>problem)]<#33966#> 
    <#33967#>[<#33967#><#33968#>e<#33968#><#33969#>lse<#33969#> 
      <#33970#>(c<#33970#><#33971#>ombine-solutions<#33971#> 
        <#33972#>problem<#33972#> 
        <#33973#>(generative-recursive-fun<#33973#> <#33974#>(generate-problem<#33974#> <#33975#>problem)))]<#33975#><#33976#>))<#33976#> 
If we replace <#66305#><#33980#>trivially-solvable?<#33980#><#66305#> with <#66306#><#33981#>empty?<#33981#><#66306#> and <#66307#><#33982#>generate-problem<#33982#><#66307#> with <#66308#><#33983#>rest<#33983#><#66308#>, the outline <#66309#><#33984#>is<#33984#><#66309#> a template for a list-processing function:
<#33989#>(d<#33989#><#33990#>efine<#33990#> <#33991#>(generative-recursive-fun<#33991#> <#33992#>problem)<#33992#>
  <#33993#>(c<#33993#><#33994#>ond<#33994#> 
    <#33995#>[<#33995#><#33996#>(empty?<#33996#> <#33997#>problem)<#33997#> <#33998#>(determine-solution<#33998#> <#33999#>problem)]<#33999#> 
    <#34000#>[<#34000#><#34001#>e<#34001#><#34002#>lse<#34002#> 
      <#34003#>(c<#34003#><#34004#>ombine-solutions<#34004#> 
        <#34005#>problem<#34005#> 
        <#34006#>(generative-recursive-fun<#34006#> <#34007#>(rest<#34007#> <#34008#>problem)))]<#34008#><#34009#>))<#34009#> 

<#34015#>Exercise 26.2.1<#34015#> Define <#66310#><#34017#>determine-solution<#34017#><#66310#> and <#66311#><#34018#>combine-solutions<#34018#><#66311#> so that the function <#66312#><#34019#>generative-recursive-fun<#34019#><#66312#> computes the length of its input.~ external Solution<#66313#><#66313#>
This discussion raises the question whether there is a difference between between functions based on structural recursion and those based on generative recursion. The answer is ``it depends.'' Of course, we could say that all functions using structural recursion are just special cases of generative recursion. This ``everything is equal'' attitude, however, is of no help if we wish to understand the process of designing functions. It confuses two classes of functions that are designed with different approaches and that have different consequences. One relies on a systematic data analysis and not much more; the other requires a deep, often mathematical, insight into the problem-solving process itself. One leads programmers to naturally terminating functions; the other requires a termination argument. A simple inspection of a function's definition quickly shows whether a function uses structural or generative recursion. All self-applications of a structurally recursive function always receive an immediate component of the current input for further processing. For example, for a <#66314#><#34027#>cons<#34027#><#66314#>tructed list, the immediate components are the <#66315#><#34028#>first<#34028#><#66315#> item and the <#66316#><#34029#>rest<#34029#><#66316#> of the list. Hence, if a function consumes a plain list and its natural recursion does not consume the rest of the list, its definition is not structural but generative. Or, put positively, properly recursive algorithms consume newly generated input, which may or may not contain components of the input. In any case, the new piece of data represents a different problem than the given one, but still a problem of the same general class of problems.