I would personally go with the syntax-parameter approach. Another option is:
(define-syntax (module-begin stx) (syntax-case stx () [(_ . body) (with-syntax ([add (datum->syntax stx 'add)] [get (datum->syntax stx 'get)]) (syntax/loc stx (#%module-begin (define state null) (define (add v) (set! state (cons v state))) (define (get) state) . body)))])) But that puts add and get into the module, which means they can't use those names, etc. I'm not sure what complexity you are worried about with the stxparam version, but this may help: #lang racket/base (require racket/stxparam racket/splicing (for-syntax racket/base racket/syntax racket/list)) (begin-for-syntax (define local-state empty) (define local-state-fs empty)) (define-syntax-rule (define-invocation-local-state id init) (begin (begin-for-syntax (set! local-state (cons #'(id init) local-state))) (define-syntax-parameter id (λ (stx) (raise-syntax-error 'id "Local state" stx))))) (define-syntax-rule (define-invocation-local-state-dependent-function (f . args) . body) (begin (begin-for-syntax (set! local-state-fs (cons #'(f args body) local-state-fs))) (define-syntax-parameter f (λ (stx) (raise-syntax-error 'f "Local state" stx))))) (define-syntax (module-begin stx) (syntax-case stx () [(_ . body) (with-syntax* ([((local-state-id local-state-init) ...) local-state] [((local-f local-f-args local-f-body) ...) local-state-fs] [(local-f-new-id ...) (generate-temporaries #'(local-f ...))]) (syntax/loc stx (#%module-begin (define local-state-new-id local-state-init) ... (splicing-syntax-parameterize ([local-state-id (make-rename-transformer #'local-state-new-id)] ...) (define (local-f-new-id . local-f-args) . local-f-body) ...) (splicing-syntax-parameterize ([local-f (make-rename-transformer #'local-f-new-id)] ...) (begin . body)))))])) (define-invocation-local-state state null) (define-invocation-local-state-dependent-function (add v) (set! state (cons v state))) (define-invocation-local-state-dependent-function (get) state) (provide (except-out (all-from-out racket/base) #%module-begin) (rename-out [module-begin #%module-begin]) add get) On Tue, May 28, 2013 at 5:59 AM, Tobias Hammer <tobias.ham...@dlr.de> wrote: > Hi, > > i am trying to write a simple language that has variables that should not be > shared, i.e that should be local to an invocation of the module-language. > > Example: > ;; ------------------------------- > #lang racket > > ;; lang > (module lang racket > (provide (all-from-out racket) > add get) > > (define state null) > > (define (add v) > (set! state (cons v state))) > > (define (get) > state)) > > ;; mods > (module m (submod ".." lang) > (add 'from-m) > (get)) > > (module n (submod ".." lang) > (add 'from-n) > (get)) > > (require 'm) > (require 'n) > ;; ------------------------------- > > This gives > '(from-m) > '(from-n from-m) > > but what i want is > '(from-m) > '(from-n) > > That means the state-variables should be unique to n and m. The allowed > functions inside the modules should at best be all from 'module context, but > at least require and provide should be possible. > > I tried overwriting #%module-begin and wrap the module body in parameterize, > but this limits to expression-context. syntax-parameters with > splicing-syntax-parameterize didn't work without converting everything in > lang to macros which would add a lot of complexity. > > So, the question is, what is the right way to get the desired behavior? > > Tobias > > > > -- > --------------------------------------------------------- > Tobias Hammer > DLR / Robotics and Mechatronics Center (RMC) > Muenchner Str. 20, D-82234 Wessling > Tel.: 08153/28-1487 > Mail: tobias.ham...@dlr.de > ____________________ > Racket Users list: > http://lists.racket-lang.org/users -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 ____________________ Racket Users list: http://lists.racket-lang.org/users