[racket] macro help redux

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Tue Jun 8 21:07:31 EDT 2010

Can you post your macro and the example that produces the expansion you 
included in your previous message? My earlier answer was based on a 
conjecture about how your macro behaved, and it would be easier to 
provide a complete answer if I can see exactly what you're doing.


Todd O'Bryan wrote:
> It does, but I'm confused. Does that mean that any macro I define that
> includes something like a contract has to require every predicate it
> could conceivably want? How do I define a macro that will allow me to
> specify a predicate later, maybe even one that didn't exist when I
> wrote the macro? Or is that not possible?
> Or, and this kind of makes sense as I'm writing it, is there a way to
> tell a macro to wait to evaluate something in the location it's used,
> rather than in its own scope?
> Todd
> On Tue, Jun 8, 2010 at 5:57 PM, Ryan Culpepper <ryanc at ccs.neu.edu> wrote:
>> Todd O'Bryan wrote:
>>> I feel like I'm getting there, but macros still do things that confuse me.
>>> According to the Macro Stepper, I've written a macro that expands to:
>>> (module fields racket
>>>  (#%module-begin
>>>   (require "tables.rkt")
>>>   (require "../date-utils.rkt")
>>>   (begin
>>>     (define-struct
>>>      date-field
>>>      (contract)
>>>      #:transparent)
>>>     (define (create-date-field
>>>              #:contract
>>>              (contract db-date?))
>>>       (make-date-field contract))
>>>     (provide/contract
>>>      (create-date-field
>>>       (-> #:contract any/c date-field?))))))
>>> At the next step of the expansion, I get the error:
>>> expand: unbound identifier in module
>>> db-date?
>>> The only problem is that "../date-utils.rkt" provides db-date? and if
>>> I put everything inside the #%module-begin into its own DrRacket
>>> definitions window, it runs without error. For some reason, db-date?
>>> isn't available when it's needed, but I can't figure out how to make
>>> it available.
>>> What am I doing wrong?
>> Is your macro defined in "tables.rkt"? If that's the case, it doesn't matter
>> whether the module where it's *used* imports date-utils, but whether the
>> module where the macro is *defined* imports date-utils. That's the idea of
>> hygienic macros; they're lexically scoped.
>> You can use the macro stepper to check an identifier's binding by clicking
>> on the identifier (here, the reference to 'db-date?'), then opening the
>> "Syntax properties" pane using the Stepper window. It'll tell you what
>> bindings, if any, the identifier refers to.
>> Did that help?
>> Ryan

Posted on the users mailing list.