[racket] macro help redux

From: Todd O'Bryan (toddobryan at gmail.com)
Date: Tue Jun 8 22:12:48 EDT 2010

Let me see if I can make a smaller example that does the same thing.
The one I'm currently working on is a big mess...

On Tue, Jun 8, 2010 at 9:07 PM, Ryan Culpepper <ryanc at ccs.neu.edu> wrote:
> 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.
> Ryan
> 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.