A typical solution for converting a recursive process to an iterative process is to enlist the aid of an accumulator.
Any way you slice it, repeated
will have to return a procedure. One solution would use a named let
inside the returned procedure that iterates n
times, keeping track of the results in an accumulator. Here is a version of repeated
that returns a unary procedure; note that there is no input validation here, so calls like ((repeated f 0) 'arg)
will lead to trouble.
(define (repeated f n)
(lambda (x)
(let iter ((n n)
(acc x))
(if (= n 1) (f acc)
(iter (- n 1)
(f acc))))))
Named let
expressions are very handy for things like this, but you could also define a helper procedure to do the same thing. I will leave that solution as an exercise for OP.
scratch.rkt> ((repeated sqr 3) 2)
256
scratch.rkt> ((repeated add1 8) 6)
14