Question

The problem can be found at http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_thm_1.37

The problem is to expand a continuing fraction in order to approximate phi. It suggests that your procedure should be able to calculate phi by evaluating:

(cont-frac (lambda (i) 1.0)
           (lambda (i) 1.0)
           k)

My solution is as follows:

(define (cont-frac n d k)
 (if (= k 1) d
     (/ n (+ d (cont-frac n d (- k 1))))))

This solution works when calling (cont-frac 1 1 k), but not when using the lambda expressions as the problem suggests. I get what looks like a type error

;ERROR: "ex-1.37.scm": +: Wrong type in arg1 #<CLOSURE <anon> (x) 1.0>
; in expression: (#@+ #@d (#@cont-frac #@n #@d (#@- #@k 1)))
; in scope:
;   (n d k)  procedure cont-frac
; defined by load: "ex-1.37.scm"

;STACK TRACE
1; ((#@if (#@= #@k 1) #@d (#@/ #@n (#@+ #@d (#@cont-frac #@n #@d  ...

My question is two-part:

Question 1. Why am I getting this error when using the lambda arguments? I (mistakenly, for sure) thought that (lambda (x) 1) should evaluate to 1. It clearly does not. I'm not sure I understand what it DOES evaluate to: I presume that it doesn't evaluate to anything (i.e., "return a value" -- maybe the wrong term for it) without being passed an argument for x.

It still leaves unanswered why you would have a lambda that returns a constant. If I understand correctly, (lambda (x) 1.0) will always evaluate to 1.0, regardless of what the x is. So why not just put 1.0? This leads to:

Question 2. Why should I use them? I suspect that this will be useful in ex-1.38, which I've glanced at, but I can't understand why using (lambda (x) 1.0) is any different that using 1.0.

Was it helpful?

Solution

In Scheme lambda expression creates a function, therefore expression such as:

(lambda (i) 1.0)

really does have result, it is a function object. But if you add parentheses around that expression, it will indeed be evaluated to 1.0 as you expected:

((lambda (i) 1.0))

Using of lambdas in that exercise is necessary for building general solution, as you've correctly noticed in exercise 1.38, you'll be using the same implementation of cont-frac function but with different numerator and denominator functions, and you'll see an example, where you should calculate one of them in runtime using loop counter.

You could compare your exercise solutions with mine, e.g. 1.37 and 1.38

OTHER TIPS

 (/ n (+ d (cont-frac n d (- k 1))))))

In this case 'd' being the lambda statement, it doesn't make any sense to '+' it, same for 'n' and '/' try something like

 (/ (n k) (+ (d k) (cont-frac n d (- k 1))))))

you'll see why in the next exercise you can also make this tail-recursive

I named my variables F-d and F-n instead of d and n, becuase they accept a function that calculates the numerator and denominator terms. (lambda (i) 1.0) is a function that accepts one argument and returns 1.0, 1.0 is just a number. In other continued fractions, the value may vary with the depth (thus why you need to pass k to the numerator and denomenator function to calculate the proper term.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top