If you want two or more top-level closures to share the same lexical variables, you can use this trick:
(define increment (if #f #f)) (define decrement (if #f #f)) (let ((shared-var 0)) (set! increment (lambda () (set! shared-var (+ shared-var 1)) shared-var)) (set! decrement (lambda () (set! shared-var (- shared-var 1)) shared-var)))
This use of DEFINE in combination with SET! is kind of verbose and far from elegant. It's better to use the DEFINE-VALUES macro, available in several Scheme implementations. Defining it with syntax-rules is a bit messy though. The following definition is used by Gauche:
;; Copyright (c) 2000-2003 Shiro Kawai (define-syntax define-values (syntax-rules () ((_ (var ...) expr) (define-values-sub () (var ...) (var ...) expr)) ((_ . else) (syntax-error "malformed define-values" (define-values . else))) )) (define-syntax define-values-sub (syntax-rules () ((_ (tmp ...) () (var ...) expr) (begin (define var (undefined)) ... (receive (tmp ...) expr (set! var tmp) ... (undefined)))) ((_ (tmp ...) (v v2 ...) (var ...) expr) (define-values-sub (tmp ... tmp1) (v2 ...) (var ...) expr)) ))
Using DEFINE-VALUES the variable-sharing closures can be rewritten more elegantly and concisely:
(define-values (increment decrement)
(let ((shared-var 0))
(values
(lambda () (set! shared-var (+ shared-var 1)) shared-var)
(lambda () (set! shared-var (- shared-var 1)) shared-var))))