[racket] hygienic read-macros (was: module-level definitions vs. local definitions and how binding works)

From: Roman Klochkov (kalimehtar at mail.ru)
Date: Mon Jul 28 03:49:00 EDT 2014

You may use such macro for making hygienic read-macros

(define-syntax (make-reader stx)
    (syntax-case stx ()
      [(_ NAME BODY ...)
       (with-syntax ([GENSYM (datum->syntax stx (gensym))])
         #'(begin
             (define-syntax (GENSYM stx)
               (syntax-case stx ()
                 [(_ in src line col pos) BODY ...]))
             (provide GENSYM)
             (define NAME
               (case-lambda
                 [(ch in)
                  (datum->syntax #f '(GENSYM in #f #f #f #f))]
                 [(ch in src line col pos)
                  (datum->syntax #f '(GENSYM in src line col pos))]))))]))

Usage example:
(make-reader read-dollar
               #'(lambda (x) x))

(current-readtable 
   (make-readtable (current-readtable)
                   #\$ 'terminating-macro read-dollar))

Test:
> $
#<procedure>
> (let ([lambda 1]) $)
#<procedure>

All works just fine

Sun, 27 Jul 2014 20:10:48 -0400 от "Alexander D. Knauth" <alexander at knauth.org>:
>It seems like “hygienic reader extensions” still work when a module-level definition conflicts with it, but it seems like if it’s a local binding the local binding overrides the one in the reader extension.  
>
>For example:
>#lang rackjure
>;; this works:
>(define lambda "module-level-whatever")
>#λ(void %1) ; #<procedure>
>;; this doesn't work
>(let ([lambda "local-whatever"]
>      [%1 void]
>      [define-syntax void]
>      [% void])
>  #λ(void %1)) ; application: not a procedure;
>;              ;   expected a procedure that can be applied to arguments
>;              ;   given: "local-whatever"
>;              ;   arguments…:
>
>Why does it work at the module-level and not within a let? 
>
>Is this a bug, or should reader extensions not be used this way, or what?  
>
>What’s going on here?
>
>
>____________________
>  Racket Users list:
>   http://lists.racket-lang.org/users
>


-- 
Roman Klochkov


Posted on the users mailing list.