#lang racket ; The problem with the general pattern is that there is work to be done ; after the recursion returns. We can move the recursive call into tail ; position by also passing down into the recursion the work to be done. ; The helper function fn-r takes the current x value and an additional ; builder function cc whose job is to do the work that would have been ; done on return. ; The builder function cc has a single argument, smaller-result, which is the ; result from the recursion that cc is associated with. ; Note how fn-r is in tail-position (define fn-r (lambda (current-x cc) (if (AtBase? current-x) ; when you get to the base case, you invoke the builder funtion ; to construct the result for the base case (cc (BaseCase current-x)) ; if you are not a base case, you decompose into a smaller case, ; and also define a builder function that combines the current ; case and the recursion result (fn-r (Decomp current-x) ; this combined the smaller-result and current-x, and then ; "returns" that into the body of cc which is the next pending ; computation. (lambda (smaller-result) (cc (Combine current-x smaller-result))) ) ) ) ) ; the function is defined in terms of the helper and a builder that simply ; returns the final result. (define fn (lambda (current-x) (fn-r current-x (lambda (smaller-result) smaller-result)) )) ; you can take advantage of the default argument feature of racket ; to avoid the helper function. If the cc argument is missing then ; the default identity function is used. (define fn-cc (lambda (current-x [cc (lambda (x) x)] ) (if (AtBase? current-x) ; when you get to the base case, you invoke the builder funtion ; to construct the result for the base case (cc (BaseCase current-x)) ; if you are not a base case, you decompose into a smaller case, ; and also define a builder function that combines the current ; case and the recursion result (fn-cc (Decomp current-x) ; this combined the smaller-result and current-x, and then ; "returns" that into the body of cc which is the next pending ; computation. (lambda (smaller-result) (cc (Combine current-x smaller-result))) ) ) ) )