[Back]

3.1 赋值和局部状态

3.1

(define (make-accumulator iter)
    (lambda (addend)
        (begin (set! iter (+ iter addend))
                iter)))

3.2

(define (make-monitored f)
    (let ((encounter 0))
        (define (how-many-calls?)
            encounter)
        (define (reset-count)
            (set! encounter 0))
        (define (dispatch m)
            (cond ((eq? m `how-many-calls?) (how-many-calls?))
                  ((eq? m `reset-count) (reset-count))
                  (else (begin (set! encounter (+ encounter 1)) (f m)))))
        dispatch))

3.3

(define (make-account balance secret)
    (define (withdraw amount)
        (if (>= balance amount)
            (begin (set! balance (- balance amount))
                    balance)
                    "Insufficient funds"))
    (define (deposit amount)
        (set! balance (+ balance amount))
        balance)
    (define (dispatch pass m)
        (cond ((not (eq? pass secret)) (lambda (money) (display "Incorrect Password")))
              (else (cond ((eq? m `withdraw) withdraw)
                          ((eq? m `deposit) deposit)
                          (else (display "Unknown request -- MAKE-ACCOUNT" m))))))
    dispatch)

3.4

(define (make-account balance secret)
    (let ((wrong-doings 0))
        (define (withdraw amount)
            (if (>= balance amount)
                (begin (set! balance (- balance amount))
                balance)
                "Insufficient funds"))
        (define (deposit amount)
            (set! balance (+ balance amount))
            balance)
        (define (dispatch pass m)
            (cond ((not (eq? pass secret)) 
                (if (< wrong-doings 6)
                    (begin (set! wrong-doings (+ wrong-doings 1)) (lambda (money) (display "Incorrect Password")))
                        (lambda (money) (display "Call the Police!"))))
                  (else (cond ((eq? m `withdraw) withdraw)
                              ((eq? m `deposit) deposit)
                              (else (display "Unknown request -- MAKE-ACCOUNT" m))))))
        dispatch))

3.5

(define (estimate-integral p x1 x2 y1 y2 trial-times)
    (define (exp)
        (p (random-in-range x1 x2) (random-in-range y1 y2)))
    (define (monte-carlo trials experiment)
        (define (iter trials-remaining trials-passed)
            (cond ((= trials-remaining 0) (/ trials-passed trials))
                ((experiment) (iter (- trials-remaining 1) (+ trials-passed 1)))
                (else (iter (- trials-remaining 1) trials-passed))))
        (iter trials 0))
    (let ((estimate-rate (monte-carlo trial-times exp)))
        (* estimate-rate (* (- x2 x1) (- y2 y1)))))
(define unit-circle
    (lambda (x y)
        (<= 1.0 (+ (* x x) (* y y)))))

3.6

(define random
    (let ((x 114514))
        (define generate
            (begin (set! x (random-update x))
                    x))
        (define reset
            (lambda (m) (set! x m)))
        (define (dispatch m)
            (cond ((eq? m `generate) generate)
                  ((eq? m `reset) reset)
                  (else (display "Unknown operation -- Rand" m))))
        dispatch))

3.7

(define (make-account balance password)
    (let ((wrong-doings 0)
          (secret (list password)))
        (define (withdraw amount)
            (if (>= balance amount)
                (begin (set! balance (- balance amount))
                    balance)
                    "Insufficient funds"))
        (define (deposit amount)
            (set! balance (+ balance amount))
                balance)
        (define (dispatch pass m)
            (cond ((not (element-of-set? pass secret)) 
                (if (< wrong-doings 6)
                    (begin (set! wrong-doings (+ wrong-doings 1)) (lambda (money) (display "Incorrect Password")))
                        (lambda (money) (display "Call the Police!"))))
                  (else (cond ((eq? m `withdraw) withdraw)
                              ((eq? m `deposit) deposit)
                              ((eq? m `join) (lambda (new-pass) (set! secret (cons new-pass secret))))
                              (else (display "Unknown request -- MAKE-ACCOUNT" m))))))
        dispatch))
(define (make-joint account secret new-pass)
    (begin ((account secret `join) new-pass) account))

3.8

(define (f m)
	(let ((x 0))
		(begin x (set! x m))))