[racket] Macro that Generate Names

From: Doug Williams (m.douglas.williams at gmail.com)
Date: Thu Sep 23 10:24:09 EDT 2010

Consider the following macro that has a definitional macro, define-x, that
stores a function definition in a structure bound to a generated name, and a
macro that either calls that stored function or it does something else. [I
used a generated name, x:<name>, because I need to use the original for
another purpose - illustrated here by just calling the stored function.]

#lang racket

(struct x-info (name func))

(define-syntax (define-x stx)
  (syntax-case stx ()
    ((define-x (name . parameters) . body)
     (with-syntax ((id (datum->syntax
                        (syntax define-x)
                        (string->symbol
                         (format "x:~a" (syntax->datum #'name))))))
       #'(define-values (id name)
           (let ((func (lambda parameters . body)))
             (values (x-info 'name func) func)))))))

(define-syntax (do-x stx)
  (syntax-case stx ()
    ((do-x (name . arguments))
     (with-syntax ((id (datum->syntax
                        (syntax define-x)
                        (string->symbol
                         (format "x:~a" (syntax->datum #'name))))))
       (if (identifier-binding #'id)
           #'((x-info-func id) . arguments)
           #'(name . arguments))))))

(provide (all-defined-out))

Now, I reference this in a separate module:

#lang racket

(require "x-2.ss")

(define (dummy a b c)
  (printf "dummy: ~a ~a ~a~n" a b c))

(define-x (my-x a b c)
  (printf "my-x: ~a ~a ~a~n" a b c))

(do-x (my-x 1 2 3))
(my-x 1 2 3)
(do-x (dummy 1 2 3))

And, when I run it I get the desired results.

my-x: 1 2 3
my-x: 1 2 3
dummy: 1 2 3

Now, the question is whether this is the 'right' way to do this and are
there any 'gotchas' that I'm not aware of? Is there something better to use
than relying on identifier-binding to return #f when there is no binding?
And, whatever obvious questions I don't even know enough to ask.

In the actually application, I am using syntax-parse to parse a rather more
complicated syntax. Is there any way in syntax-parse I can define a syntax
class that would recognize a class of identifier based on their bindings?

Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100923/8fde2f23/attachment.html>

Posted on the users mailing list.