Vityou, > even though (class ...) expands into a function where method-list is defined.
It does not expand into a function where method-list is defined because it does not expand in that way. The macro "define/method" is called with the given syntax and the macro operates on that syntax (it's just a procedure that takes a syntax argument and evaluates to syntax) and where the macro lives, "method-list" is neither defined nor given as part of use of the syntax. So the macro introduces it's own "method-list", so something in the background like "method-list7734", which isn't your "method-list" but since the macro's own "method-list" doesn't exist, set! doesn't know what to do, and you get an error. This is a combination of how procedures work and how hygiene works in macros. One way to manage this is to make it part of the syntax: ;;;;; (define-syntax (define/method stx) (syntax-parse stx [(_ (name ML arg ...) body) #'(begin (define (name arg ...) body) (set! ML (cons `(name ,name) ML)))])) (define (make-person name age) (define (obj arg) (define method-list '()) (define/method (get-name method-list) name) (second (assq arg method-list))) obj) ;;;;; Then it expands as you expect, because it's operating on the syntax you have given it. Another way: the macro can be coerced to use an identifier which it doesn't understand by breaking the hygiene barrier ;;;;; define-syntax (define/method stx) (syntax-parse stx [(_ (name arg ...) body) (with-syntax ((ML (datum->syntax stx 'method-list))) #'(begin (define (name arg ...) body) (set! ML (cons `(name ,name) ML))))])) ;;;;; Now this macro assumes the identifier "method-list" exists in whatever context the code expands in, which is the behavior you expect. Normally we don't want to break hygiene. For instance, if a macro's code introduced some temporaries like "num" or "x" or something, we wouldn't want those temporaries to shadow or otherwise clobber some innocent macro-user's own use of these identifiers. When we call a procedure like "displayln" we don't need to worry that the author of the code used some name for some local identifier. Since macros are just racket procedures, too, the same reasoning applies: we don't want to worry that when we call a macro it might use some name we've already used. In your case, this is your exact intention, so racket allows you to break this protective mechanism explicitly. Deren -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.