In Common Lisp, if I want two functions to share state, I would perform a let over lambda as follows:
(let ((state 1))
(defun inc-state ()
(incf state))
(defun print-state ()
(format t "~a~%" state))
These functions are not local to the let
- they are global functions that maintain a reference to a shared state variable, which itself is not visible from outside. For example, I could do the following elsewhere in my code:
(print-state) => 1
(inc-state) => 2
(print-state) => 2
In Scheme, however, such a construct declares local functions, that are not visible from outside:
(let ((state 1))
(define (print-state)
(print state))
(print-state)) => 1
(print-state) => error, no such variable print-state
The only way I can think to achieve this kind of functionality (aside from using un-exported globals inside a module), would be something like this:
(define print-state #f)
(define inc-state #f)
(let ((state 1))
(set! print-state (lambda () (print state)))
(set! inc-state (lambda () (inc! state))))
Is there a way in Scheme to write the let-over-lambda form without resorting to such ugly workarounds? Or would I need to write a macro to wrap this ugliness? (Btw I know about letrec
, and that's not a solution to this problem.)
Incidentally, I'm using Chicken Scheme, but my question should be relevant to all Schemes.
define-values
is less ugly than my solution. I'll still probably write a macro to wrap it though. – Deter