如何将MIT Scheme账户实现代码转换为Common Lisp?
将MIT Scheme账户闭包转换为Common Lisp
先给出你描述的MIT Scheme典型实现:
(define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (dispatch msg) (cond ((eq? msg 'withdraw) withdraw) ((eq? msg 'deposit) deposit) (else (error "Unknown request: MAKE-ACCOUNT" msg)))) dispatch)
对应的Common Lisp实现,完全保留闭包状态管理和消息分发逻辑:
(defun make-account (initial-balance) (let ((balance initial-balance)) (labels ((withdraw (amount) (if (>= balance amount) (progn (decf balance amount) balance) "Insufficient funds")) (deposit (amount) (incf balance amount) balance) (dispatch (msg) (case msg (withdraw #'withdraw) (deposit #'deposit) (t (error "Unknown request for MAKE-ACCOUNT: ~a" msg))))) #'dispatch)))
关键对应说明
- Scheme的内部
define函数 → Common Lisp用labels定义嵌套函数,配合let创建闭包保存balance状态 - Scheme的
set!变量修改 → Common Lisp用decf/incf直接操作变量,等价于(setf balance (- balance amount))但更简洁 - Scheme的
cond消息分发 → Common Lisp用case做模式匹配,更符合Lisp语法习惯 - 调用方式差异:
- Scheme:
((acc 'withdraw) 50) - Common Lisp:
(funcall (funcall acc 'withdraw) 50)(Lisp中函数对象需用funcall触发调用)
- Scheme:
使用示例
;; 创建初始余额100的账户 (setf my-account (make-account 100)) ;; 取款50,返回当前余额50 (funcall (funcall my-account 'withdraw) 50) ;; 存款30,返回当前余额80 (funcall (funcall my-account 'deposit) 30) ;; 尝试取款100,返回错误提示 (funcall (funcall my-account 'withdraw) 100)
内容的提问来源于stack exchange,提问作者JimmeyNeutron
相关产品推荐
相关产品推荐

