While reading *rackunit* source I stumbled on a pattern that I can't figure out. Why the heck does it work? Condensed to its essence it amounts to introducing indirection with a macro-generated define:
#lang racket > (require (for-syntax syntax/parse) > syntax/parse/define) > (define-simple-macro (define-foo (name:id formal:id ...) body:expr ...) > (begin > (define (foo-impl formal ...) body ...) > (define-syntax (name stx) > (syntax-parse stx > [(_ . args) #'(foo-impl . args)] > [_:id #'(λ args (apply foo-impl args))])))) > (define-foo (bar op a b) (op a b)) > (define-foo (baz op a b) (op a b)) > ;; Why am I not getting this error? > ;; -------------------------------- > ; module: identifier already defined > ; at: foo-impl See that *foo-impl* there? The same name is being reused every time the *define-foo* macro is called. I would've expected Racket to shout at me that I'm attempting to redefine something, but it doesn't and magically it works. Why? Say, in Elisp or Clojure I would've gensymed that symbol. What am I missing? Does Racket perform some clever renaming to preserve hygiene or something? Could someone please help me reason through this. Original source: https://github.com/racket/rackunit/blob/master/rackunit-lib/rackunit/private/check.rkt#L110 PS: also I left that second clause there just cause it just dawned on me how cool it is that we can use macros in identifier position :) -- 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.