;; file: 3_01.rkt
(#%require rackunit)
(define (make-accumulator initial-value)
(let ((cached initial-value))
(lambda (x)
(set! cached (+ x cached))
cached)))
(define A (make-accumulator 5))
(check-equal? (A 10) 15)
(check-equal? (A 10) 25)
;; file: 3_02.rkt
(#%require rackunit)
(define (make-monitored fn)
(let ((call-count 0))
(lambda (x)
(if (eq? x 'how-many-calls?)
call-count
(let ((result (fn x)))
(set! call-count (inc call-count))
result)))))
(define s (make-monitored sqrt))
(check-equal? (s 100) 10)
(check-equal? (s 'how-many-calls?) 1)
;; file: 3_03.rkt
;; 3_03 / 3_04 / 3_07
(#%require rackunit)
(#%require (prefix racket: racket))
(racket:provide make-account)
(define (make-account balance initial-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 m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
(define (password-dispatch password m)
(if (not (eq? password initial-password))
(lambda (amount)
"Incorrect password")
(dispatch m)))
password-dispatch)
(define acc (make-account 100 'secret-password))
(check-equal? ((acc 'secret-password 'withdraw) 40) 60)
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
;; file: 3_04.rkt
;; 3_03 / 3_04 / 3_07
(#%require rackunit)
(define (make-account balance initial-password)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (call-the-cops amount)
'call-the-cops)
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
((eq? m 'call-the-cops) call-the-cops)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
(let ((wrong-password-count 0))
(define (password-dispatch password m)
(if (not (eq? password initial-password))
(begin
(set! wrong-password-count (inc wrong-password-count))
(if (>= wrong-password-count 7)
(dispatch 'call-the-cops)
(lambda (amount)
"Incorrect password")))
(dispatch m)))
password-dispatch))
(define acc (make-account 100 'secret-password))
(check-equal? ((acc 'secret-password 'withdraw) 40) 60)
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) "Incorrect password")
(check-equal? ((acc 'some-other-password 'deposit) 50) 'call-the-cops)
;; file: 3_05.rkt
;; file: 3_06.rkt
(#%require rackunit)
(define (rand-update x)
(let ((a 27) (b 26) (m 127))
(modulo (+ (* a x) b) m)))
(define random-init 7)
(define rand
(let ((x random-init))
(define (reset new-value)
(set! x new-value))
(define (generate)
(set! x (rand-update x))
x)
(define (dispatch m)
(cond ((eq? m 'generate)
(generate))
((eq? m 'reset)
reset)))
dispatch))
(check-equal? (rand 'generate) 88)
(check-equal? (rand 'generate) 116)
(check-equal? (rand 'generate) 110)
((rand 'reset) 7)
(check-equal? (rand 'generate) 88)
(check-equal? (rand 'generate) 116)
(check-equal? (rand 'generate) 110)
;; file: 3_07.rkt
;; 3_03 / 3_04 / 3_07
(#%require rackunit)
(#%require (prefix racket: racket))
(racket:require (racket:only-in "3_03.rkt" make-account))
(define (make-joint account account-password new-password)
(define (dispatch password m)
(if (not (eq? password new-password))
(lambda (amount)
"Incorrect password")
(account account-password m)))
dispatch)
(define peter-acc (make-account 100 'open-sesame))
(check-equal? ((peter-acc 'open-sesame 'withdraw) 40) 60)
(define paul-acc
(make-joint peter-acc 'open-sesame 'rosebud))
(check-equal? ((paul-acc 'rosebud 'withdraw) 40) 20)
;; file: 3_08.rkt
(#%require rackunit)
(define make-f nil)
(define f nil)
(define (make-f-1)
(let ((cached 'undefined))
(define (inner-f x)
(if (eq? cached 'undefined)
(begin
(set! cached x)
x)
0))
inner-f))
(set! make-f make-f-1)
(set! f (make-f))
(check-equal? (let ((x (f 0))
(y (f 1)))
(+ x y))
0)
(set! f (make-f))
(check-equal? (let ((y (f 1))
(x (f 0)))
(+ x y))
1)
(define (make-f-2)
((lambda (old)
(define (inner-f x)
(let ((temp old))
(set! old x)
temp))
inner-f)
0))
(set! make-f make-f-2)
(set! f (make-f))
(check-equal? (let ((x (f 0))
(y (f 1)))
(+ x y))
0)
(set! f (make-f))
(check-equal? (let ((y (f 1))
(x (f 0)))
(+ x y))
1)
;; file: 3_09.rkt
;; file: 3_10.rkt
;; file: 3_11.rkt
;; file: 3_12.rkt
;; 3_12 / 5_22
(#%require rackunit)
(#%require "../allcode/helper/my-util.rkt")
(#%require (prefix racket: racket))
(#%require threading)
;; TODO
(define (append x y)
(if (null? x)
y
(cons (car x) (append (cdr x) y))))
(define (append! x y)
(set-cdr! (last-pair x) y)
x)
(define (last-pair x)
(if (null? (cdr x))
x
(last-pair (cdr x))))
(define x1 '(1 2))
(define y1 '(3 4))
(check-equal? (append x1 y1)
'(1 2 3 4))
(check-equal? x1 '(1 2))
(check-equal? y1 '(3 4))
(define x2 '(1 2))
(define y2 '(3 4))
(check-equal? (append! x2 y2)
'(1 2 3 4))
(check-equal? x2 '(1 2 3 4))
(check-equal? y2 '(3 4))
;; file: 3_13.rkt
;; file: 3_14.rkt
;; file: 3_15.rkt
;; file: 3_16.rkt
;; file: 3_17.rkt
;; file: 3_18.rkt
;; file: 3_19.rkt
;; file: 3_20.rkt
;; file: 3_21.rkt
;; file: 3_22.rkt
;; file: 3_23.rkt
;; file: 3_24.rkt
;; file: 3_25.rkt
;; file: 3_26.rkt
;; file: 3_27.rkt
;; file: 3_28.rkt
;; file: 3_29.rkt
;; file: 3_30.rkt
;; file: 3_31.rkt
;; file: 3_32.rkt
;; file: 3_33.rkt
;; file: 3_34.rkt
;; file: 3_35.rkt
;; file: 3_36.rkt
;; file: 3_37.rkt
;; file: 3_38.rkt
;; file: 3_39.rkt
;; file: 3_40.rkt
;; file: 3_41.rkt
;; file: 3_42.rkt
;; file: 3_43.rkt
;; file: 3_44.rkt
;; file: 3_45.rkt
;; file: 3_46.rkt
;; file: 3_47.rkt
;; file: 3_48.rkt
;; file: 3_49.rkt
;; file: 3_50.rkt
;; file: 3_51.rkt
;; file: 3_52.rkt
;; file: 3_53.rkt
;; file: 3_54.rkt
;; file: 3_55.rkt
;; file: 3_56.rkt
;; file: 3_57.rkt
;; file: 3_58.rkt
;; file: 3_59.rkt
;; file: 3_60.rkt
;; file: 3_61.rkt
;; file: 3_62.rkt
;; file: 3_63.rkt
;; file: 3_64.rkt
;; file: 3_65.rkt
;; file: 3_66.rkt
;; file: 3_67.rkt
;; file: 3_68.rkt
;; file: 3_69.rkt
;; file: 3_70.rkt
;; file: 3_71.rkt
;; file: 3_72.rkt
;; file: 3_73.rkt
;; file: 3_74.rkt
;; file: 3_75.rkt
;; file: 3_76.rkt
;; file: 3_77.rkt
;; file: 3_78.rkt
;; file: 3_79.rkt
;; file: 3_80.rkt
;; file: 3_81.rkt
;; file: 3_82.rkt