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.mccar...@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.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
--
---------------------------------------------------------
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