Reputation: 1
does anybody know how can I create a function in Scheme that takes no arguments and everytime I call it returns 0 or 1, depending on how many times it's been called? For example, the 1st time returns 1, the 2nd 0, the 3rd 1, etc.
I suppose I have to use a local variable inside the function, but I don't know exactly how, so that it changes value everytime I call it.
Upvotes: 0
Views: 425
Reputation: 18937
If you only need one procedure of this kind, you can also do as follows:
(define flip
(let ((x 1))
(lambda ()
(begin0
x
(set! x (- 1 x))))))
Testing:
> (flip)
1
> (flip)
0
> (flip)
1
> (flip)
0
Upvotes: 0
Reputation: 66459
Your code doesn't work because you're overusing parentheses, which makes your code try to call "procedures" that aren't procedures.
Your code,
(define (make-flip)
(let ((x 1))
(lambda ()
((set! x (- 1 x))
(if (= x 0) (1) (0))))))
attempts the procedure calls (0)
and (1)
, and it also tries to "call" the result of the sequence
(set! x (- 1 x))
(if (= x 0) (1) (0)))
(Scheme never ignores any parentheses the way some other languages do.)
If you fix those,
(define (make-flip)
(let ((x 1))
(lambda ()
(set! x (- 1 x))
(if (= x 0) 1 0))))
it works.
The conditional isn't necessary though, you can also say
(define (make-flip)
(let ((x 0))
(lambda ()
(set! x (- 1 x))
x)))
and get the same result.
Upvotes: 0
Reputation: 158
You didn't say how you are calling your function. Did you define some named function as the lambda you return with you make-flip
function? I guess this is "making closures 101" but it's the first time I've done to my recollection. Anyway, I tried this way and it seemed to work:
(define (make-flipper)
(let ((flip 0))
(lambda ()
(set! flip (if (= flip 0) 1 0))
flip)))
(define doit (make-flipper))
(doit)
(doit)
(doit)
--results in 1, then 0, then 1. I guess you could change the value in the let if you want it to start with 0.
Upvotes: 1