[racket] hygienic read-macros (was: module-level definitions vs. local definitions and how binding works)
Well that works fine when it’s in the same module (or namespace), but when I put it in a #lang, it breaks and I get this error:
experiment-with-hygenic-reader-extensions/try-it.rkt:
#lang experiment-with-hygenic-reader-extensions
$
; g15667: unbound identifier in module in: g15667
That’s one problem with unhygienic reader extensions.
Since you used (datum->syntax #f ‘(GENSYM …)), it eventually took on the lexical context of try-it.rkt, where the GENSYM name isn’t there.
Though strangely, if I put some lexical context on GENSYM by using (datum->syntax #f `(,#'GENSYM …)), then it gives me this error:
experiment-with-hygenic-reader-extensions-2/try-it.rkt:
#lang experiment-with-hygenic-reader-extensions-2
$
; require: namespace mismatch;
; reference to a module that is not available
; reference phase: 0
; referenced module: “…/experiment-with-hygenic-reader-extensions-2/lang/reader.rkt"
; referenced phase level: 0 in: g24
https://github.com/AlexKnauth/experiment-with-hygenic-reader-extensions
On Jul 28, 2014, at 3:49 AM, Roman Klochkov <kalimehtar at mail.ru> wrote:
>
> 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