Common Lisp では、2 つの関数で状態を共有したい場合、次のようにlet over ラムダを実行します。
(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))))
そのような醜い回避策に頼ることなく、 let-over-lambdaフォームを書く方法は Scheme にありますか? それとも、この醜さをラップするマクロを書く必要がありますか? (ところで、私は について知っていletrec
ますが、それはこの問題の解決策ではありません。)
ちなみに、私はチキンスキームを使用していますが、私の質問はすべてのスキームに関連するはずです。