在 Common Lisp 中,如果我想要两个函数共享状态,我会执行一个let over lambda,如下所示:
(let ((state 1))
(defun inc-state ()
(incf state))
(defun print-state ()
(format t "~a~%" state))
这些函数不是本地的let
- 它们是维护对共享状态变量的引用的全局函数,该变量本身从外部是不可见的。例如,我可以在代码的其他地方执行以下操作:
(print-state) => 1
(inc-state) => 2
(print-state) => 2
然而,在 Scheme 中,这样的构造声明了局部函数,这些函数从外部是不可见的:
(let ((state 1))
(define (print-state)
(print state))
(print-state)) => 1
(print-state) => error, no such variable print-state
我能想到实现这种功能的唯一方法(除了在模块中使用未导出的全局变量)是这样的:
(define print-state #f)
(define inc-state #f)
(let ((state 1))
(set! print-state (lambda () (print state)))
(set! inc-state (lambda () (inc! state))))
在 Scheme 中有没有一种方法可以编写let-over-lambda形式而无需求助于这种丑陋的变通方法?还是我需要编写一个宏来包装这种丑陋?(顺便说一句,我知道letrec
,这不是解决这个问题的方法。)
顺便说一句,我使用的是 Chicken Scheme,但我的问题应该与所有 Schemes 有关。