[racket] hygienic read-macros (was: module-level definitions vs. local definitions and how binding works)
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