[racket] Macro defining functions question

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Thu May 15 15:24:01 EDT 2014

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

> Ok… so apparently the crucial element is the transfer of lexical context to the function id, not necessarily to the arguments or body text? I’m not sure what the rule is for this lexical transfer. For instance, the following defines bar, but not baz:
> 
> (require (for-syntax racket/syntax))
> 
> (define-syntax (foo stx)
>  (syntax-case stx ()
>    [(_)
>     (with-syntax ([bar (format-id stx "~a" #'bar)]
>                   [y (format-id stx "~a" #'y)])
>       #'(begin
>         (define (bar x) x)
>         (define (baz y) y)))]))
> 


Correct. format-id and datum->syntax use stx to move lexical-context properties from the place where (foo ...) is located to these identifiers generated in the definition of foo. Since bar is generated with format-id, it receives the (foo ...) context while baz is simply written down as is and does not get these properties. 

The rule is simple. The default use of lexical context is usually exactly what you want. In rare cases you want to break this protocol. If you discover that you wish to break the protocol: 
  (1) think again 
  (2) consider passing the name into the macro so that naming protocol becomes obvious 
  (3) and if you reject (1) and (2), proceed with extreme caution. 



> Incidentally the macro stepper shows bar in the define differently colored from the rest of the definition, while it shows y in the baz definition as being differently colored. I’m not sure what the color key is though! 

Click on the identifiers to inspect their properties. 




Posted on the users mailing list.