[racket] variables within macros

From: Ray Racine (ray.racine at gmail.com)
Date: Wed Jan 16 11:06:26 EST 2013

Oh yea,

An example of use:
Define a layout of field types and lengths, then when creating a text line
parser you give it the fields you want, and you get a (: Orderline-parser
(String -> Orderline)) where Orderline is an implicitly created struct:


(define-fixed-layout Orderline-layout
  (order C 11)
  (order-sub C 5)
  (line C 7)
  (account C 10)
  (address-seq C 7)
  (create-date D 10)
  (order-type S 1)
  (location C 4)
  (dept C 2)
  (class C 3)
  (sku C 20)
  (vendor C 2)
  (entered-sku C 20)
  (source C 2)
  (list-price N 9)
  (sku-price N 10)
  (cost N 10)
  (uom C 2)
  (pack-qty I 7)
  (order-qty I 7)
  (ship-qty I 7)
  (misc-charge S 1)
  (sub-flag S 1)
  (contract-pp C 9)
  (contract-pp-seq C 5)
  (commission N 9)
  (contract-addendum C 1))

(define-static-parser-for-layout (Orderline-parser Orderline-layout)
  (order sku create-date order-type dept class))


On Wed, Jan 16, 2013 at 10:56 AM, Ray Racine <ray.racine at gmail.com> wrote:

> 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/ea1b9eff/attachment.html>

Posted on the users mailing list.