SICP 的创建帐户代码中的 deposit 和 withdraw 程序都有看似无用的 balance 变量表达式来计算,
这样做的实际目的是什么? (对我来说,这似乎是多余的代码和平,但我不认为 Abelson 和 Sussman 会放一些无用的东西)。
同时,在 DrRacket [从 IDE 运行] 中,会打印来自 withdraw 的 balance,而来自 deposit 的 balance 不会打印。这是为什么?这是 DrRacket 的问题、错误还是什么。
在 Chicken计划和 MIT 计划 [从命令行运行] 中,deposit 和 withdraw 的 balance 打印不一致。
代码如下。我刚刚添加了(显示“存款: ”) 和 (显示“提现: ") 为方便起见,改为原始代码。 所讨论的 balance 变量表达式就位于显示表达式之后,位于同一行代码中。
#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)
例如,这是 Dr.Racket 的输出,
withdraw:
deposit:
100
withdraw 不打印任何内容,deposit 打印“100”。为什么不打印两者或都不打印?
withdraw:
被打印为 (display "withdraw:\n")
deposit:
被打印为 (display "deposit:\n")
100
由 REPL 打印为 (exchange a1 a2)
Scheme 实现和 IDE 与 REPL 之间的行为差异可以通过以下方式解释:
begin
define
、set!
和 display
具有未指定的返回值,因此实现可以返回它想要的任何内容(根据优化细节,它甚至可能在不同的运行中有所不同)不是无用的余额是关闭返回值。此代码中未使用它,但可能有用:
(define a3 (make-account 100))
(display (string-append "balance: "
(number->string ((a3 'deposit) 10))
"\n"))
;; ==> deposit:
;; ==> balance: 110