[racket] Macro defining functions question

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Thu May 15 13:09:43 EDT 2014

On May 15, 2014, at 12:32 PM, Kevin Forchione <lysseus at gmail.com> wrote:

> This one leaves me scratching my head. Why doesn’t this work? When you run the macro the functions aren’t defined outside of the extent of the begin.
> 
> (define-syntax (foo stx)
>  (syntax-case stx ()
>    [(foo)
>     #'(begin
>         (define (bar x) x)
>         (define (baz x) x))]))
> 
> After inning the macro (bar 3) produces an bar undefined error. 


Racket's macro system is hygienic, which means that by default, the lexical context of the macro usage is kept apart from the macro definition. 


> On the other hand, this works:
> 
> (define-syntax (defstruct-lite stx)
>  (syntax-case stx ()
>    [(defstruct-lite name field ...)
>     (let ([make-id
>            (lambda (template . ids)
>              (let ([str (apply format template (map syntax->datum ids))])
>                (datum->syntax stx (string->symbol str))))])


The above line explicitly transfers the lexical context from the original syntax to the 'made up' make names. Hence these identifiers are now in the same scope as the original syntax (dubbed stx). 




Posted on the users mailing list.