[racket] variables within macros
On the topic of "state" propagation across macros by extending the
expansion environment (or whatever the terminology would be). I have an
example where a macro is used to define a layout of a fixed offset text
file. Then a second macro expands into a mini field parser based on the
layout definition. Frankly my first macro beyond a basic syntax-rules
sort, so it's rough and assuredly less than optimal. It can be found here.
https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/layout-types.rkt
https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/layout.rkt
https://github.com/RayRacine/racketlib/blob/mapred/RpR/format/parser.rkt
On Wed, Jan 16, 2013 at 10:33 AM, Danny Yoo <dyoo at hashcollision.org> wrote:
> On Wed, Jan 16, 2013 at 7:24 AM, Tim Brown <tim.brown at cityc.co.uk> wrote:
> > Folks,
> >
> > I would like to write a module that uses a macro to transform "define"s
> > and accumulate a value based on those transformations.
> >
> > In a fairly simple way, I want to do something like the below. However,
> it
> > seems the module-begin is being transformed before the my-defines. How do
> > I get counter to be incremented before I need it?
>
> The transformation happens top-down, so you'll see that the body of
> your program expands in the following steps (to a first
> approximation):
>
>
> (#%your-module-begin (your-define woo 2))
>
> ==>
>
> (#%racket-module-begin (your-define woo 2)
> (define defines-counter 0)
> (provide defines-counter))
>
> ==>
>
> (#%racket-module-begin (racket-define woo 2)
> (define defines-counter 0)
> (provide defines-counter))
>
>
> One possible workaround is the the following: add one level of
> indirection in installing the value of the defines-counter. You can
> do something like:
>
> (define-syntax (get-counter stx)
> (datum->syntax stx counter))
>
> and use (get-counter) in place of #,counter in your module-begin.
> This way, we delays the lookup of counter until the macro expander
> finally reaches that expression, and by that time, it should have hit
> all the defines already.
>
>
> If you need to control the order of expansion more explicitly, you may
> need to look into local-expand:
>
>
> http://docs.racket-lang.org/reference/stxtrans.html#(def._((quote._~23~25kernel)._local-expand))
>
> ----
>
> Modified code below:
>
> #lang racket/base
>
> (provide (except-out (all-from-out racket) #%module-begin define)
> (rename-out (module-begin #%module-begin) (my-define define)))
>
> (require (for-syntax racket/base
> syntax/parse))
> (define-for-syntax counter 0)
>
> (define-syntax (my-define stx)
> (syntax-parse
> stx
> [(_ i v) (set! counter (add1 counter)) #`(define i v)]
> [(_ (i args ...) v ...+) (set! counter (add1 counter))
> #`(define (i args ...) v ...)]))
>
> (define-syntax (get-counter stx )
> (datum->syntax stx counter))
>
> (define-syntax (module-begin stx)
> (syntax-parse
> stx
> [(_ expr ...)
> #`(#%module-begin expr ...
> (define defines-count (get-counter))
> (provide defines-count))]))
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130116/9857d8c6/attachment-0001.html>