syntax-define-values


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)))) 

category-code