George P.
George P.

Reputation: 1

Flip function in Scheme

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

Answers (3)

uselpa
uselpa

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

molbdnilo
molbdnilo

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

EvansWinner
EvansWinner

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

Related Questions