Your procedure returns a new procedure. In Scheme you have this way of making a variable:
(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:
(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.
(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:
(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:
(func 10) ; ==> 16
As for an example of procedures that return procedures. Imagine you have a procedure that sums two squares and divides:
(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:
(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:
(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.
I'm the author of
two useless languages that uses
BF as target machine.
Currently I'm planning a Scheme compiler :p