Scheme function that returns function is returning unexpected value
Question
I have a function in scheme
(define (m-m f)
(let ((count 0))
(define (h-m-c?) count)
(define (r-c) (begin (set! count 0) count))
(define (m-f m)
(cond ((eq? m 'h-m-c?) (h-m-c))
((eq? m 'r-c) (r-c))
(else (set! count (+ 1 count)) f)))
m-f))
where m-f is a function that is returned.
However, rather than returning a value, it returns
#<procedure:m-f>
It appears there is no error with the code, so why doesn't this return a usable value?
Solution
You told it to return m-f
. That's the name of a procedure that you defined, so it's returning the procedure. To use this return value, you need to assign it to another variable.
(define thing1 (m-m 'unused))
(define thing2 (m-m 'who-cares))
(thing1 'h-m-c?)
(thing1 'increment)
(thing1 'h-m-c?)
(thing2 'h-m-c?)
Some other commentary:
Procedure names ending in ?
are used for predicates that report true/false.
You don't need begin
in (r-c)
. Procedure bodies allow multiple expressions, and execute them in order just like begin
.
Why didn't you define a function for the case where count
is incremented, like you did for the other cases?
Using the default for incrementing seems inappropriate, you should require a specific m
parameter for this.
What's the purpose of the f
parameter? The only thing it's used for is to be returned when incrementing? Wouldn't the new value of count
be a more useful return value? It seems like it's intended to be a "name" for the instance; if so, perhaps you should add a new operation to return the name, rather than doing this when incrementing.
EDIT:
Based on the answer below, I suspect you're misusing the f
parameter. It's probably supposed to be a function that you call when doing the increment. So you need to supply it as a lambda expression, and return (f)
rather than just f
.