1

I am trying to implement a function called funPower, which takes a function f, an integer n and returns the function f^n. For example ((funPower sqrt 2) 16) should return 2, which is (sqrt (sqrt 16)).

This is what I have so far but it is not giving me correct output

(define (funPower f n)
  (lambda(x) (if (<= n 1)
            (f x)
            (f (funPower f (- n 1)) x))))
3
  • 2
    What have you tried/done? This looks like a homework problem, and we can't do homework for you. Commented Sep 25, 2020 at 4:26
  • Can you explain in more detail how ((funPower sqrt 2) 16) is supposed to return 2? What were the operations you did there? Commented Sep 25, 2020 at 8:38
  • @ÓscarLópez He wants a function that waits for an input and applies N times a function F on that input. For example, \x->sqrt(sqrt(x)). It's a problem from SICP as far as remember. Commented Sep 25, 2020 at 12:55

2 Answers 2

2

First, you're missing one more pair of parens.

(define (funPower1 f n)
  (lambda (x) (if (<= n 1)
            (f x)
         ;; (f (   funPower1 f (- n 1)) x))))
            (f ( ( funPower1 f (- n 1)) x)))) )
         ;;     ^^^                          ^^^

because (funPower1 f (- n 1)) returns a function to be called on x, the future argument value, as you show with the example, ((funPower sqrt 2) 16).

Second, it's <= 0, not <= 1, and the function f shouldn't be called at all in such a case:

(define (funPower2 f n)
  (lambda (x) (if (<= n 0)
         ;; (f x)      ^^^
               x 
            (f ( ( funPower2 f (- n 1)) x)))) )

Now that it's working, we see that it defers the decisions to the final call time, of ((funPower f n) x). But it really could do all the decisions upfront -- the n is already known.

To achieve that, we need to swap the (lambda and the (funPower, to push the lambda "in". When we do, it'll become an additional argument to such augmented funPower:

(define (funPower3 f n)
  (if (<= n 0) (lambda (x) 
               x )
    (funPower3 f (- n 1) (lambda (x) (f x)))) )

Now this is completely out of sync. Where's that third argument?

(define (funPower4 f n fun)
  (if (<= n 0) fun
    (funPower4 f (- n 1) (lambda (x) (fun (f x)))) ))

That's a little bit better, but what's the fun, originally? Where does it come from? It must always be (lambda (x) x) at first or else it won't be right. The solution is to make it an internal definition and use that, supplying it the correct argument the first time we call it:

(define (funPower5 f n)
  (define (loop n fun)
    (if (<= n 0) fun
      (loop (- n 1) 
            (lambda (x) (fun (f x))))))
  (loop n (lambda (x) x)))

This kind of thing would normally be coded as a named let,

(define (funPower5 f n)
  (let loop ((n  n) 
             (fun (lambda (x) x)))
    (if (<= n 0) fun
      (loop (- n 1) 
            (lambda (x) (fun (f x)))))))

We could also try creating simpler functions in the simpler cases. For instance, we could return f itself if n is 1:

(define (funPower6 f n)
  (cond 
    ((zero? n) .....)
    ((= n 1)   .....)
    ((< n 0)   .....)
    (else
      (let loop ((n  n) 
                 (fun .....))
        (if (= n .....) fun
          (loop (- n 1) 
            (lambda (x) (fun (f x)))))))))

Complete it by filling in the blanks.

More substantive further improvement is to use exponentiation by repeated squaring -- both in constructing the resulting function, and to have it used by the function we construct!

Sign up to request clarification or add additional context in comments.

Comments

1

try this:

(define funpow
  (lambda (f n)
    ((lambda (s) (s s n (lambda (x) x)))
     (lambda (s n o)
       (if (zero? n)
           o
           (s s (- n 1)
              (lambda (x)
                (o (f x)))))))))

    
(define sqrt_2 (funpow sqrt 2))
(define pow2_2 (funpow (lambda (x) (* x x)) 2))

(sqrt_2 16)
(pow2_2 2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.