I am new to Lisp and im trying to define a function.
This is the code i managed to write:
(define (func n)
(lambda (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
((= n odd?) (+ (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
But when I make a call, it doesn't compute it. For example, when i type (func 17), it returns "#<procedure>". So how do I make it compute a call?
how do I run this procedure?
Re: how do I run this procedure?
Your procedure returns a new procedure. In Scheme you have this way of making a variable:
Then you have this abbrivation for the special case where the value is a procedure:
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.
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:
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:
As for an example of procedures that return procedures. Imagine you have a procedure that sums two squares and divides:
Now you see a pattern there so you must be able to abstract that so it becomes smaller:
Now you could do this:
But you could also make use of closures and do it like this:
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.
Code: Select all
(define test 10)
(define test-proc (lambda (n) (+ n n))
Code: Select all
(define (test-proc n) (+ n n))
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
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
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
Code: Select all
(define (sum-square a b)
(+ (* a a)
(* b b)))
(define (divide-square a b)
(/ (* a a)
(* b b)))
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))
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 /))
I'm the author of two useless languages that uses BF as target machine.
Currently I'm planning a Scheme compiler :p
Currently I'm planning a Scheme compiler :p