[racket] Problem with Unhygienic Provide-Syntax
I tried to define some "marked" identifiers, and provide them using
"(all-defined-out)" with the same mark. The marks are introduced
unhygienicaly.
The problem is that some in additional marks are introduced during the
expansion, so in the example
"(provide (all-defined-marked-out))"
provides only the identifier "one", but does not provide the identifier "two".
(See the "Short Example" code below.)
I couldn't find a short and elegant solution. I want to know if there
is a better way to do this.
In my solution, the big changes were:
(See the "Long Example" code in the attached files.)
* In provide-trampoline: Add a few syntax-local-introduce to cancel
the syntax-marks before the expansion and mark them again after the
expansion.
* In make-provide-macro: Save the temporal syntax-introducer in a
parameter to be able to call it with "my-syntax-local-introduce" to
break hygiene. I think that it is not possible to modify the marker in
"syntax-local-introduce", so I created my own version.
And some small changes:
* In provide: It calls my versions of provide-trampoline.
* In define-provide-syntax: It calls my versions of make-provide-macro.
;=== begin provide-short-example.rkt
#lang racket/base
(require "provide-short.rkt")
(provide (all-defined-marked-out)) ;Provides: one :(
(provide-all-defined-marked-out) ;Provides: one, two :)
(define one 1)
(define-marked two 2)
;=== end provide-short-example.rkt
; ------------------------------------
;=== begin provide-short.rkt
#lang racket/base
(require (for-syntax racket/base))
(require racket/provide-syntax)
(provide (all-defined-out))
; *** extra-marker ***
(define-for-syntax extra-marker (make-syntax-introducer))
; *** define ***
(define-syntax (define-marked stx)
(syntax-case stx ()
[(_ var val) (identifier? #'var)
(with-syntax ([mk-var (syntax-local-introduce
(extra-marker
(syntax-local-introduce #'var)))])
#'(define mk-var val))]))
; *** provide ***
(define-syntax (provide-all-defined-marked-out stx)
(syntax-case stx ()
[(_) (with-syntax ([\mk-all-defined-out/
(syntax-local-introduce
(extra-marker
(syntax-local-introduce
(datum->syntax stx (syntax-e
#'(all-defined-out))))))])
#'(provide \mk-all-defined-out/))]))
(define-provide-syntax (all-defined-marked-out stx)
(syntax-case stx ()
[(_) (syntax-local-introduce
(extra-marker
(syntax-local-introduce
(datum->syntax stx (syntax-e #'(all-defined-out))))))]))
;=== end provide-short.rkt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: provide-example.rkt
Type: application/octet-stream
Size: 421 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20120202/f61eac18/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: provide.rkt
Type: application/octet-stream
Size: 4806 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20120202/f61eac18/attachment-0003.obj>