I'm unclear why I'm getting an unbound-identifier error in this macro. I've written other self-referencing macros in the past that have worked, so I'm unclear why this one doesn't.
What I expect is that when `definer` is called with one argument, the first branch of `syntax-case` will stick on a default argument and call `definer` again. Which it does, except that in that case, it only binds the name 'id' rather than both 'id' and 'arg-id'. #lang racket (require (for-syntax racket/syntax) rackunit) (define-syntax (definer stx) (syntax-case stx () [(_ id) #'(definer id zam)] [(_ id arg) (with-syntax ([arg-id (format-id stx "~a-~a" #'arg #'id)]) #'(begin (define id (quote id)) (define arg-id (quote arg-id))))])) (definer foo-id bar) (check-equal? foo-id 'foo-id) (check-equal? bar-foo-id 'bar-foo-id) (definer baz-id) (check-equal? baz-id 'baz-id) (check-equal? zam-baz-id 'zam-baz-id) ;; unbound identifier error OTOH, this version of the macro, which repeats the expansion template rather than calling itself, works fine: #lang racket (require (for-syntax racket/syntax) rackunit) (define-syntax (definer2 stx) (syntax-case stx () [(_ id) (with-syntax ([arg-id (format-id stx "~a-~a" (format-id stx "zam") #'id)]) #'(begin (define id (quote id)) (define arg-id (quote arg-id))))] [(_ id arg) (with-syntax ([arg-id (format-id stx "~a-~a" #'arg #'id)]) #'(begin (define id (quote id)) (define arg-id (quote arg-id))))])) (definer2 foo-id bar) (check-equal? foo-id 'foo-id) (check-equal? bar-foo-id 'bar-foo-id) (definer2 baz-id) (check-equal? baz-id 'baz-id) (check-equal? zam-baz-id 'zam-baz-id) ;; no error this time ____________________ Racket Users list: http://lists.racket-lang.org/users