Common Lisp-style macros in Racket

Today I put myself together and read a couple of sections of Racket documentation. Now I finally know how to implement Common Lisp-style macros in Racket. I'm still not 100% sure it will work exactly as expected but common cases work right.

Here it is:

(define-syntax define-macro
  (syntax-rules ()
   ((_ name fn)
    (define-syntax (name stx)
      (datum->syntax stx (apply fn (cdr (syntax->datum stx))))))))

(define-macro mac
  (lambda (sig . body)
    (cond ((symbol? sig) `(define-macro ,sig ,@body))
          ((pair? sig)   `(define-macro ,(car sig) (lambda ,(cdr sig) ,@body)))
          (else           (error "wrong use of mac")))))

This will give you macro-defining macro mac as in Paul Graham's Arc, except that I defined it in a Scheme way. You will easily figure out how to use it from this example:

(mac (with var exp . body)
    `((lambda (,var) ,@body) ,exp))

(with a 2 (+ a  4)) ; => 6

UPD: In case you want to write a macro that makes use of a function defined in the same file this will not work. But it can easily be fixed by defining this function with define-with-syntax as described here.