3
votes

I am learning Scheme by 'Structure and Interpretation of Computer Programs'

In Chapter 1.3.2 Constructing Procedures Using lambda.

I understood lambda like this.

The value to match the lambda is written outside the parenthesis of the lambda.

((lambda (x) (+ x 4) 4) ; (x) is matched to 4, result is 8

But in SICP, another example code is different.

The code is :

(define (sum x y) (+ x y))

(define (pi-sum a b)
  (sum (lambda (x) (/ 1.0 (* x (+ x 3))))
        a
        (lambda (x) (+ x 4))
        b
         ))

(pi-sum 3 6)

I think if (lambda (x) (/ 1.0 (* x (+ x 3)))) want match to a, lambda and a must bound by parenthesis.

But in example code, don't use parenthesis.

When I run this code, error is occurs.

error is this :

***'sum: expects only 2 arguments, but found 4'***

When I use more parenthesis like this :

(define (sum x y) (+ x y))

(define (pi-sum a b)
  (sum ((lambda (x) (/ 1.0 (* x (+ x 3))))
        a)
        ((lambda (x) (+ x 4))
        b)
         ))

(pi-sum 2 6) ; result is 10.1

Code is run.

I'm confused because of SICP's example code.

Am I right on the principle of lambda?

If I am right, why SICP write like that?

1

1 Answers

3
votes

It says to use the sum from 1.3.1. On page 77 (actually starting on 77 and ending on 78) it looks like this:

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

As you can see it looks a lot different from your sum that just adds two number together. You also had a typo in pi-sum:

(define (pi-sum a b)
  (sum (lambda (x) (/ 1.0 (* x (+ x 2)))) ; multiplied by 2, not 3!
       a
       (lambda (x) (+ x 4))
       b))

(* 8 (pi-sum 1 1000))
; ==> 3.139592655589783

So the point here is that you can pass lambdas instead of named procedures. Since (define (name . args) body ...) is just syntax sugar for (define name (lambda args body ...)) passing (lambda args body ...) instead of defining it and pass a name is just an equal refactoring.

Parentheses around a variable (+) or a lambda ((lambda args body ...)) calls whatever procedure the operator expression evaluates. It is not what you want since you pass procedures to be used by sum as an abstraction. sum can do multiplications or any number of things based on what you pass. in sum term is the procedure (lambda (x) (/ 1.0 (* x (+ x 2)))) and you see it calls it as apart of its code.