Reputation: 1288
The deposit and withdraw procedures in the make-account code from SICP both have seemingly useless balance variable expression to evaluate,
What is the practical purpose for doing that? (To me it seems redundant peace of code, but I don't think Abelson and Sussman would put something useless).
Meanwhile, in DrRacket [run from IDE], the balance from withdraw gets printed, whereas the balance from deposit does not. Why is that? Is it a DrRacket's thing, a bug, or what.
In Chicken Scheme and MIT Scheme [run from command line], the balance is not printed consistently for both deposit and withdraw.
The code is below. I just added (display "deposit:\n") and (display "withdraw:\n") to the original code for convenience. The balance variable expression in question is right after the display expressions, on the same line of code.
#lang racket
(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
(display "withdraw:\n") balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
(display "deposit:\n") balance)
(define (dispatch m)
(cond ((eq? m 'deposit) deposit)
((eq? m 'withdraw) withdraw)
((eq? m 'balance) balance)
(else
(error "Unknown request: MAKE-ACCOUNT" m))))
dispatch)
(define (exchange account1 account2)
(let ((difference (- (account1 'balance)
(account2 'balance))))
((account1 'withdraw) difference)
((account2 'deposit) difference)))
(define a1 (make-account 100))
(define a2 (make-account 75))
(exchange a1 a2)
E.g., here is the output from Dr.Racket,
withdraw:
deposit:
100
withdraw prints nothing, deposit prints '100'. Why not to print either both or none?
Upvotes: 0
Views: 108
Reputation: 796
withdraw:
is printed as the side effect of (display "withdraw:\n")
deposit:
is printed as the side effect of (display "deposit:\n")
100
is printed as the return value of (exchange a1 a2)
Variations in behavior between Scheme implementations and IDE vs. REPL may be explained by:
begin
define
, set!
, and display
have unspecified return values, so an implementation can return whatever it wants (it might even be different from run to run depending on optimization details)Upvotes: 1
Reputation: 66610
It's not useless balance is the closure return value. It's not used in this code but may be useful:
(define a3 (make-account 100))
(display (string-append "balance: "
(number->string ((a3 'deposit) 10))
"\n"))
;; ==> deposit:
;; ==> balance: 110
The value will also be printed if you execute in REPL:
> (define a4 (make-account 100))
> ((a4 'deposit) 10)
;; ==> deposit:
;; ==> 110
This code will behave the same in every Scheme.
Upvotes: 1