λ3.1節
問題 3.1
問題 3.2
問題 3.3
問題 3.4
問題 3.5
問題 3.6
問題 3.7
問題 3.8
問題 3.1
(define (make-accumulator init)
(let ((sum init))
(lambda (inc)
(begin (set! sum (+ sum inc))
sum))))
(define A (make-accumulator 5))
(A 10)
(A 10)
問題 3.2
(define (make-monitored f)
(let ((counter 0))
(lambda (x)
(if (eq? x 'how-many-calls?) counter
(begin (set! counter (+ counter 1))
(f x))))))
問題 3.3
(define (make-account balance password)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (skip amount)
"Incorrect password")
(define (dispatch p m)
(if (eq? p password)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m)))
skip))
dispatch)
(define acc (make-account 100 'secret-password))
((acc 'secret-password 'withdraw) 40) → 60
((acc 'some-other-password 'deposit) 50) → "Incorrect password"
問題 3.4
(define (call-the-cops) "call-the-cops")
(define (make-account balance password)
(define count 0)
(define (withdraw amount)
(set! count 0)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! count 0)
(set! balance (+ balance amount))
balance)
(define (skip amount)
(set! count (+ count 1))
(if (>= count 7)
(call-the-cops)
"Incorrect password"))
(define (dispatch p m)
(if (eq? p password)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m)))
skip))
dispatch)
問題 3.5
(define (square x) (* x x))
(define (estimate-integral P x1 x2 y1 y2 trials)
(define (test)
(P (random-in-range x1 x2) (random-in-range y1 y2)))
(let ((rsquare (* (- x2 x1) (- y2 y1))))
(* (monte-carlo trials test) rsquare)))
(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))
(define (random-in-range low high)
(let ((range (- high low)))
(+ low (random range))))
(estimate-integral
(lambda (x y) (<= (+ (square (- x 5)) (square (- y 7))) 9))
2.0 8.0 4.0 10.0 1000)
問題 3.6
(define rand
(let ((x random-init))
(lambda (symbol)
(cond ((eq? symbol 'generate) (set! x (rand-update x)) x)
((eq? symbol 'reset) (lambda (new-value) (set! x new-value) x))
(else (error "Unknown symbol --- RAND" symbol))))))
問題 3.7
(define (make-account balance password)
(define new-password 0)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (skip amount)
"Incorrect password")
(define (joint p)
(set! new-password p)
(lambda (p m)
(if (eq? p new-password)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m)))
skip)))
(define (dispatch p m)
(if (eq? p password)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'joint) joint)
(else (error "Unknown request -- MAKE-ACCOUNT"
m)))
skip))
dispatch)
(define (make-joint old-acc old-password new-password)
((old-acc old-password 'joint) new-password))
(define peter-acc (make-account 100 'open-sesame))
((peter-acc 'open-sesame 'withdraw) 50) → 50
((peter-acc 'rosebud 'deposit) 30) → "Incorrect password"
(define paul-acc (make-joint peter-acc 'open-sesame 'rosebud))
((paul-acc 'rosebud 'deposit) 30) → 80
((paul-acc 'open-sesame 'withdraw) 20) → "Incorrect password"
問題 3.8
(define f
(let ((x 0))
(lambda (n)
(if (= x 0) (begin (set! x 1) n) 0))))
(display (f 0)) (newline)
(display (f 1)) (newline)
(define f
(let ((x 0))
(lambda (n)
(if (= x 0) (begin (set! x 1) n) 0))))
(display (f 1)) (newline)
(display (f 0)) (newline)
または
(define f
(let ((x 0) (y 0))
(lambda (z) (set! y x) (set! x z) y)))