0
#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?

Will Ness
  • 70,110
  • 9
  • 98
  • 181

2 Answers2

1

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
Renzo
  • 26,848
  • 5
  • 49
  • 61
0

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).

Will Ness
  • 70,110
  • 9
  • 98
  • 181