song qi
song qi

Reputation: 1

sicp 1.44 why it is a #<procedure>

#lang planet neil/sicp

(define dx 0.00001)

(define (smooth-n f n)
  (repeat smooth f n))

(define (smooth f)
  (lambda (x) (/ (+ (f x) (f (- x dx)) (f (+ x dx))) 3)))

(define (compose f g)
  (lambda (x) (f (g x))))

(define (repeat f g n) 
   (define (iter n result) 
     (if (< n 1) 
         result 
         (iter (- n 1) (compose f result)))) 
   (iter n (lambda (x) (g x))))

(define (square x) (* x x))

((smooth-n square 3) 2)     ---> #<procedure>

what did I miss?

Upvotes: 0

Views: 165

Answers (2)

Renzo
Renzo

Reputation: 27424

The problem is in the definition of repeat, which has an extra parameter. In the previous exercise it is required to define a function repeat that applied to a function f and a positive number n returns a new function, let call it fn, that applies f to its argument n times. repeat then could be defined as:

(define (repeat f n)
  (if (= n 1)
      f
      (compose f (repeat f (- n 1)))))

or, if you prefer a tail-recursive version, as:

(define (repeat f n)
  (define (iter n result)
    (if (= n 1)
        result
        (iter (- n 1) (compose f result))))
  (iter n f))

For instance:

((repeat square 2) 2)
16

since fn is the function that calculates the square of the square of its argument.

Given this definition, then smooth-n could be defined as:

(define (smooth-n f n)
  ((repeat smooth n) f))

that is: get the function obtained applying smooth n times, and apply it to f, so that the result is the n-fold smoothed version of f.

So that:

((smooth-n square 3) 2)
4.0000000002

Upvotes: 1

Will Ness
Will Ness

Reputation: 71065

According to your definitions we have

((smooth-n square 3) 2)
=
((repeat smooth square 3) 2)
=
((compose smooth (compose smooth (compose smooth square))) 2)
=
(smooth (smooth (smooth (square 2))))
=
(smooth (smooth (smooth 4)))

but you wanted to get ((smooth (smooth (smooth square))) 2). Redefining

(define (repeat f g n) 
   (define (iter n result) 
     (if (< n 1) 
         result 
         (iter (- n 1) (f result)))) 
   (iter (- n 1) (f g)))

takes care of it (returning 4.000000000266667). But it's really non-idiomatic; you should go with the solution in the other answer instead. (leaving this here for comparison).

Upvotes: 0

Related Questions