The key insight to understand here is that in Scheme we can pass functions as parameters to another function as easily as we would pass, say, numbers. Be aware that the template is incomplete, it should be:
(define (<name> <term> a <next> b)
(if (> a b)
0
(+ (<term> a)
(<name> <term> (<next> a) <next> b))))
The transformation from template to actual procedure is straightforward:
<name>
is the placeholder for the name of the procedure, which happens to be sum
<term>
is the placeholder for the procedure that is applied over each term in the series, in the actual procedure it's also called term
but it could have any other name - for instance, identity
would be an useful procedure to pass along
<next>
is the placeholder for a procedure that calculates the next element in the series, for instance it could be as simple as passing along add1
, but the authors chose to also call it next
The next b
part at the end of the actual procedure is just providing the next
(a function) and b
(a number) parameters to the recursive call of the function, this is what's getting passed in the last line:
(sum term (next a) next b)
^ ^ ^ ^ ^
function call "term" function next number "next" function upper limit
Also notice that (next a)
is actually applying the next
procedure to the a
parameter, and passing along to the recursion the result of that application - in fact, this is the only value that changes between calls, and it's effectively advancing the recursion up until the point when (> a b)
becomes false. That's different from what's happening in the second-to-last parameter, where we are passing next
, the function itself and not the result of applying it. As an example, here's how you'd call the sum
procedure to add all the numbers between 1
and 10
:
(sum identity 1 add1 10) ; <term> is `identity` and <next> is `add1`
=> 55