schemesicpmit-schemecontinued-fractions

Cannot understand how we can give a procedures as actual parameter when formal parameters are used as values in scheme?


In SICP exercise 1.37

Section 1.3.3 in SICP Scroll Down to the end of section (just before 1.3.4) to find the exercise [3rd exercise in the section].

According to the problem, I defined cont-frac as

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

Link to solution for the exercise

According to the solution link the above code seems to be consistent. The problem arise in the second part of the solution when n and d are substituted as (lamda (i) 1.0), in part (a) of the solution, which is a procedure.

I can't understand how this will work when substituted in the procedure of cont-frac. When I tried, there is the error which says Wrong type of argument


Edit 1

I have added my whole solution. It solves the problem but doesn't capture the essence of the section. This is the solution to exercises 1.37, 1.38 and 1.39. The program does not use Procedure as General Method which solutions of the below links do Solution to 1.37, Solution to 1.38 and Solution to 1.39

In the below program
in the procedures phi and e-2-val, k is no of steps in continued fraction
in the procedure tan, k is angle in radians (No of steps is 1000 for accurate value)

#!/usr/local/bin/guile \
-e main -s
!#
(define (finite-cont-frac n d k)
    (if (= k 0)
        0 
        (/ n (+ d (finite-cont-frac n d (- k 1))))))

(define (e-2 n d k1 c k)
    (define (d-val) 
        (if (= (modulo k1 3) 1)
            (+ c 2)
            1))
    (define (c-val)
        (if (= (d-val) 1) c (d-val)))
    (if (= k 0)
        0 
        (/ n (+ (d-val) (e-2 n (d-val) (+ k1 1) (c-val) (- k 1))))))

(define (tan-cf n k d k1)
    (define (d-val)
        (if (= k1 0) 1 (+ d 2)))
    (if (= k 0) 
        0
        (/ n (+ (d-val) (tan-cf n (- k 1) (d-val) (+ k1 1))))))

(define (tan-man x kk)
    (let ((a (- (* x x))))
        (tan-cf a kk 1 0)))
(define rrr 80.0)
(define (main args)
    (let* ((k (string->number (list-ref args 1)))
           (phi (/ 1.0 (finite-cont-frac 1.0 1.0 k)))
           (e-2-val (e-2 1.0 1 0.0 0 k))
           (tt (/ (tan-man k 1000) (- 0.0 k))))
        (display tt)
        (newline)))


Solution

  • The linked answer looks wrong, you're supposed do pass procedures, not numbers as actual parameters. Using a helper procedure called accumulate:

    (define (accumulate combiner null-value term1 term2 a next b)
      (if (> a b)
          null-value
          (combiner (term1 a)
                    (term2 a)
                    (accumulate combiner
                                null-value
                                term1
                                term2
                                (next a)
                                next
                                b))))
    
    (define (cont-frac n d k)
      (accumulate (λ (x y rec) (/ x (+ y rec)))
                  0 n d 1 add1 k))
    

    Now we can call the procedure as expected:

    (cont-frac (lambda (i) 1.0)
               (lambda (i) 1.0)
               10)
    => 0.6179775280898876