[racket] non-shared module variables
I thought that the syntax-parameter approach with macros would add
complexity to functions with optional and/or keyword arguments. But your
solution with parameterizing over the state and then the functions solves
my problem completely.
Thanks for sharing this excellent solution!
On Tue, 28 May 2013 14:33:50 +0200, Jay McCarthy <jay.mccarthy at gmail.com>
wrote:
> 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.hammer at 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.hammer at dlr.de
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
>
>
>
--
---------------------------------------------------------
Tobias Hammer
DLR / Robotics and Mechatronics Center (RMC)
Muenchner Str. 20, D-82234 Wessling
Tel.: 08153/28-1487
Mail: tobias.hammer at dlr.de