(module bank mzscheme (provide (all-defined)) ;; *$ ;; *$@&& ;; #* && ;; && ;; && ;; && ;; && ;; && ;; && ;; && ;; && ;; &&&&&&&& ;; &&&&&&&& ;; Original version of the bank-account program ;; Using non-tail calls and mutable state (define balance 100) (define read-adjustment (lambda () (let ((adjustment (read))) (if (> adjustment 0) (if (= (read) 1234) adjustment 0) adjustment)))) (define bank (lambda () (let ((garbage1 (write balance))) (let ((garbage2 (set! balance (+ balance (read-adjustment))))) (bank))))) ;; +$@@$* ;; @&&&&&@+ ;; $* *&@ ;; &@ ;; &@ ;; #@* ;; #@* ;; #@: ;; $@ ;; #@- ;; *&# ;; &&&&&&&& ;; &&&&&&&& ;; After state-passing transformation ;; No longer using mutable state; still using non-tail calls (define read-adjustment-s (lambda () (let ((adjustment (read))) (if (> adjustment 0) (if (= (read) 1234) adjustment 0) adjustment)))) (define bank-s (lambda (balance) (let ((garbage1 (write balance))) (let ((adjustment (read-adjustment-s))) (bank-s (+ balance adjustment)))))) ;; *#@@$# ;; &&&&&&$ ;; #- :&@ ;; &@ ;; +@+ ;; &&&$: ;; &&&@# ;; #&$ ;; &@ ;; &@ ;; +- +&@ ;; &&&&&@* ;; +$@@$: ;; After continuation-passing transformation ;; No longer using mutable state or non-tail calls, ;; but now passing functions (continuations) around (define apply-c (lambda (c result) (c result))) (define read-adjustment-s-c (lambda (c) (read-c (lambda (adjustment) ;1 (if (> adjustment 0) (read-c (lambda (passcode) ;2 (if (= passcode 1234) (apply-c c adjustment) (apply-c c 0)))) (apply-c c adjustment)))))) (define bank-s-c (lambda (balance c) (write-c balance (lambda (garbage1) ;3 (read-adjustment-s-c (lambda (adjustment) ;4 (bank-s-c (+ balance adjustment) c))))))) ; read-c and write-c for use over the console (define read-c (lambda (c) (apply-c c (read)))) (define write-c (lambda (output c) (apply-c c (write output)))) ; read-c and write-c for use over the Web after defunctionalization ;(define read-c ; (lambda (c) ; (cons c '()))) ; ;(define write-c ; (lambda (output c) ; (cons output (apply-c c 'garbage)))) ;; && ;; #&& ;; -@&& ;; $+&& ;; *$ && ;; @- && ;; ## && ;; @ && ;; $&&&&&&&& ;; &&&&&&&&& ;; && ;; && ;; && ;; After defunctionalization ;; No longer using mutable state or non-tail calls, ;; and does not pass functions (continuations) around (define apply-c-d (lambda (c result) (cond ((= (car c) 1) (let ((c (cadr c)) (adjustment result)) (if (> adjustment 0) (read-c-d (list 2 adjustment c)) (apply-c-d c adjustment)))) ((= (car c) 2) (let ((adjustment (cadr c)) (c (caddr c)) (passcode result)) (if (= passcode 1234) (apply-c-d c adjustment) (apply-c-d c 0)))) ((= (car c) 3) (let ((balance (cadr c)) (c (caddr c)) (garbage1 result)) (read-adjustment-s-c-d (list 4 balance c)))) ((= (car c) 4) (let ((balance (cadr c)) (c (caddr c)) (adjustment result)) (bank-s-c-d (+ balance adjustment) c)))))) (define read-adjustment-s-c-d (lambda (c) (read-c-d (list 1 c)))) (define bank-s-c-d (lambda (balance c) (write-c-d balance (list 3 balance c)))) ; read-c-d and write-c-d for use over the console ;(define read-c-d ; (lambda (c) ; (apply-c-d c (read)))) ; ;(define write-c-d ; (lambda (output c) ; (apply-c-d c (write output)))) ; read-c-d and write-c-d for use over the Web (define read-c-d (lambda (c) (cons c '()))) (define write-c-d (lambda (output c) (cons output (apply-c-d c 'garbage)))) ;; Initialization (define bank-start (lambda () (bank-s-c-d 100 'unused-continuation))) )