#lang racket
;;;;;;;;;;
;; 3.38 ;;
;;;;;;;;;;
(define (make-account initial-balance)
(define balance initial-balance)
(define (deposit amount) (set! balance (+ balance amount)))
(define (withdraw amount) (set! balance (- balance amount)))
(define (halve) (set! balance (/ balance 2)))
(define (dispatch m)
(cond [(eq? m 'deposit) deposit]
[(eq? m 'withdraw) withdraw]
[(eq? m 'halve) halve]
[(eq? m 'balance) balance]
[else (error "Unknown message -- DISPATCH" m)]))
dispatch)
(define (peter acct) ((acct 'deposit) 10))
(define (paul acct) ((acct 'withdraw) 20))
(define (mary acct) ((acct 'halve)))
;; What are the possible final balances after allowing these three transactions to
;; be completed sequentially in any order?
(define (test sequence)
(define test-account (make-account 100))
(for ([p sequence]) (p test-account))
(test-account 'balance))
(for/list ([seq (in-permutations (list peter paul mary))])
(test seq))
;; '(40 50 40 35 45 45)
;; What are some other values that could be produced if the processes could be
;; interleaved?
;; Interleaving the processes allows us to ignore one or two commands because
;; those commands could always be executed between the third command's read and
;; write operations. So one new value would be 110, obtained by the following
;; sequence of events:
;; peter reads balance = 100
;; peter computes (+ balance 10) and gets 110
;; paul does his transaction
;; mary does her transaction
;; peter sets balance to 110
Comments
0 B
|👍
/👎
0 B
|👍
/👎