Reputation: 49
I'm working on exercise 1.43 from The Structure and Interpretation of Computer Programs.
Exercise 1.43. If f is a numerical function and n is a positive integer, then we can form the nth repeated application of f, which is defined to be the function whose value at x is f(f(...(f(x))...)). For example, if f is the function x ↦ x + 1, then the nth repeated application of f is the function x ↦ x + n. If f is the operation of squaring a number, then the nth repeated application of f is the function that raises its argument to the 2nth power. Write a procedure that takes as inputs a procedure that computes f and a positive integer n and returns the procedure that computes the nth repeated application of f. Your procedure should be able to be used as follows:
((repeated square 2) 5) 625
Hint: You may find it convenient to use
compose
from exercise 1.42.
I wrote the code like this:
(define (repeated f n)
(lambda (x)
(if (= n 1)
(f x)
(f ((repeated f (- n 1)))))))
Error:
> ((repeated square 2) 5)
...p/1.3.4-mine.rkt:22:2: arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 0
Why doesn't my code work? The correct answer is:
(define (repeated f n)
(if (= n 1)
f
(lambda (x)
(f ((repeated f (- n 1)) x)))))
Upvotes: 3
Views: 936
Reputation: 48745
First look at how you call it:
((repeated square 2) 5)
The look at how you do the recursion:
((repeated f (- n 1)))
repeated
returns a procedure that takes one argument so calling the result with no argument should signal an arity error.
In the correct answer it's passing the one required argument in the recursive call. In real life you wouldn't recreate the procedure each step though but perhaps used a named let
:
(define (repeated f n)
(if (= n 1)
f
(lambda (x)
(let loop ((acc x) (n n))
(if (zero? n)
acc
(loop (f acc) (- n 1)))))))
Upvotes: 3