(define (rand A B M)
(lambda (x)
(lambda (c)
(let ((update (lambda ()
(set! x (remainder (+ (* A x) B) M)))))
(cond ((eq? c 'reset)
(lambda (new-v) (set! x new-v)))
((eq? c 'generate)
(update)
x)
((eq? c 'random-in-range)
(lambda (low high)
(let ((renge (- high low)))
(+ low (* renge (/ (update) M))))))
(else (error "not found")))))))
(define r ((rand 997 1 65536) 12345))
(map (lambda (x) (r 'generate)) (iota 5))
((r 'reset) 12345)
(map (lambda (x) (r 'generate)) (iota 5))
(map (lambda (x) ((r 'random-in-range) 1.0 1.5)) (iota 5))
(define (make-account balance original-pass)
(let ((c 7) (pass (list original-pass)))
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (add-password newp)
(unless (memq newp pass)
(set! pass (cons newp pass)))
dispatch)
(define (call-the-cops x) "call-the-cops")
(define (dispatch p m)
(if (memq p pass)
(begin (set! c 7)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'add-password) add-password)
(else (error "Unknown request -- MAKE-ACOUNT" m))))
(begin (if (= c 0)
call-the-cops
(begin (set! c (- c 1))
(lambda (x) "Incorrect pasword!"))))))
dispatch))
(define (make-joint acc p newp)
((acc p 'add-password) newp))
(define peter-acc (make-account 100 'open-sesame))
(map (lambda (x) ((peter-acc 'open-sesame 'deposit) 10)) (iota 5))
(define paul-acc
(make-joint peter-acc 'open-sesame 'rosebud))
(map (lambda (x) ((paul-acc 'rosebud 'withdraw) 20)) (iota 5))
(define f
(let1 state 0
(lambda (n)
(let1 prev state
(set! state n)
prev))))
(+ (f 0) (f 1))
(map (lambda (x) (cons x (f x))) (iota 5))