[racket] Macros: "define" a variable with a transformed id

From: Jon Rafkind (rafkind at cs.utah.edu)
Date: Fri Aug 13 18:08:53 EDT 2010

  On 08/13/2010 03:46 PM, Christopher Bowron wrote:
> I'm trying to write a macro that takes in an id, and creates a
> variable with a name based on id, and adds a string based on id into a
> list.
>
> If I have (define-filter-category foo), I want it to add
> "CICategoryFoo" to the FILTER-CATEGORIES list as well as introduce a
> binding for the variable filter-category-foo.  I have the part that
> adds the string to the list, but I do not know how to manipulate the
> id and introduce the variable.  Can anyone shed some light on this for
> me?  Thanks
>

The short answer is hygiene is preventing you from binding identifiers 
created in the macro to escape the scope of the macro. You need to 
unhygienically introduce the identifier you want either through 
syntax-local-introduce or pass the original lexical context (from the 
macro use) to datum->syntax.

Also you it looks like you are trying to munge the names of identifiers 
in the second pattern of `define-filter-category', but you need those 
functions to run at transformation time. Code won't run in a 
syntax-rules, it just gets expanded and returned.

> What I have so far:
>
> (define FILTER-CATEGORIES empty)
>
> (define (id->category-string n)
>    (define (camel-case str)
>      (regexp-replace* #rx"-" (string-titlecase str) ""))
>    (string-append "CICategory" (camel-case (symbol->string n))))
>
> (define (id->category-id n)
>    (string->symbol (string-append "filter-category-" (symbol->string n))))
>
> (define-syntax define-filter-category
>    (syntax-rules ()
>      ((_ id string)
>       (begin
>         ;;; FIXME: also (define ,id  string)
>         (set! FILTER-CATEGORIES (cons string FILTER-CATEGORIES))))
>      ((_ name)
>       (define-filter-category
>         (id->category-id (quote name))
>         (id->category-string (quote name))))))
>
>
> (define-filter-category distortion-effect)
> (define-filter-category ...)
>



Posted on the users mailing list.