Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

don't understand scheme procedure in SICP

i'm working through SICP Chapter 1 "1.3 Formulating Abstractions with Higher-Order Procedures"

the part i'm (currently) having trouble with is where the procedural template (shown below) is transformed into an actual procedure (shown below that) by having its 'slots' turned into formal parameters. What I don't get is where the hell they get the next b at the end of the transformed procedure (just before the closing brackets)?

Surely its just b as in the template?

Anyway, this is the template...

(define (<name> a b)
  (if (> a b)
      0
      (+ (<term> a)
         (<name> (<next> a) b))))

And this is the procedure once the parameter slots have been filled in

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))

any illumination much appreciated

like image 439
user3435279 Avatar asked Jun 04 '14 13:06

user3435279


1 Answers

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
like image 137
Óscar López Avatar answered Sep 27 '22 19:09

Óscar López