Your procedure returns a new procedure. In Scheme you have this way of making a variable:

- Code: Select all
`(define test 10)`

(define test-proc (lambda (n) (+ n n))

Then you have this abbrivation for the special case where the value is a procedure:

- Code: Select all
`(define (test-proc n) (+ n n))`

It's the same as the other expression making the variable test-proc. If you look at your definition you see that you do both. So in reality you have.

- Code: Select all
`(define proc `

(lambda (n) ; this is the first layer. The procedure the variable proc will become

(lambda (n) ...) ; this is the procedure the procedure proc will return

Looking at the arguments you have n both places so the previous will definitely be overshadowed by the second. Perhaps you didn't want it to return a new procedure? In that case just remove one:

- Code: Select all
`(define (func n)`

(cond ((= n 0) 0) ;;If n=0, return 0

((= n 1) 2) ;;If n=1, return 2

((= n 2) 37) ;;If n=2, return 37

((odd? n) (+ (func (- n 3) 1))) ;;If n is odd, return f(n-3) + 1

(else (+ (func (- (/ n 2) 1)) 7)))) ;;Else return f((n/2) - 1) + 7

I noticed you are checking if the procedure odd? is the same number as n. This will never work as odd? is not a number at all but a procedure that checks if it's argument is an odd number. (odd? n) perhaps what you wanted?

In DrRacket, after pressing CTRL+i, to fix identation, I noticed the identation was off and thus that means your parentheses most likely are not correct and your program will fail (or worse, do something else than you think).

I changed it so that else comes on the level of cond. Now you can call it like this:

- Code: Select all
`(func 10) ; ==> 16`

As for an example of procedures that return procedures. Imagine you have a procedure that sums two squares and divides:

- Code: Select all
`(define (sum-square a b)`

(+ (* a a)

(* b b)))

(define (divide-square a b)

(/ (* a a)

(* b b)))

Now you see a pattern there so you must be able to abstract that so it becomes smaller:

Now you could do this:

- Code: Select all
`(define (proc-square proc a b)`

(proc (* a a)

(* b b)))

;; new version of sum-square

(define (sum-square a b)

(proce-square + a b))

;; divide the square version

(define (divide-square a b)

(proc-square / a b))

But you could also make use of closures and do it like this:

- Code: Select all
`(define (proc-square proc)`

(lambda (a b)

(proc (* a a)

(* b b))))

;; new version of sum-square

(define sum-square (proce-square +))

;; divide the square version

(define divide-square (proc-square /))

In this case it's a matter of taste, but in procedures where you need to use map or fold and need a procedure this wuld be the simplest and you don't even need to use define but pass it directly.