[plt-scheme] Problem with macro generated provide/contract
Matthew Flatt wrote:
> At Sat, 05 Nov 2005 22:14:43 +0100, Jens Axel Søgaard wrote:
>
>>(module list-signature mzscheme
>> (provide provide-list-operations)
>> (define-syntax provide-list-operations
>> (syntax-rules ()
>> [(provide-list-operations)
>> (provide mycons mycar myempty)])))
>>
>>Our original mylist1 without signatures now become:
>>
>>(module mylist2 mzscheme
>> (define mycons cons)
>> (define myempty '())
>> (define mycar car)
>>
>> (require list-signature)
>> (provide-list-operations))
>
>
> I think this shouldn't have worked. (I know why it works in the current
> implementation.)
>
> `require' and `provide' are supposed to be sensitive to the lexical
> context of specific imports/exports. In particular, a macro-introduced
> `require' is supposed to bind in the same way as a macro-introduced
> `define', and a macro-introduced `provide' is supposed to behave like a
> macro-introduced reference.
Ok.
> Since `(provide mycons ...)' is introduced in the above example from a
> context with no `mycons', then it shouldn't have worked.
>
> I'll look into fixing this bug. Then, you'd have to make
> `provide-list-operations' non-hygienic:
That makes sense.
> (define-syntax (provide-list-operations stx)
> (syntax-case stx ()
> [(_)
> (with-syntax ([mycons (datum->syntax-object stx 'mycons)]
> [mycar (datum->syntax-object stx 'mycar)]
> [myempty (datum->syntax-object stx 'myempty)])
> #'(provide mycons mycar myempty))]))
>
> This same strategy should work for `provide/contract'.
I tried this (and variations thereof):
(module list-signature-with-contracts mzscheme
(provide provide-list-operations-with-contracts)
(define-syntax provide-list-operations-with-contracts
(syntax-rules ()
[(provide-list-operations-with-contracts)
(begin
(require (lib "contract.ss"))
(define pair/c (flat-named-contract 'pair pair?))
(define-syntax (provide-list-operations stx)
(syntax-case stx ()
[(_)
(with-syntax
([mycons (datum->syntax-object stx 'mycons)]
[mycar (datum->syntax-object stx 'mycar)]
[myempty (datum->syntax-object stx 'myempty)])
#'(provide/contract
(mycons (-> any/c any/c pair/c))
(mycar (-> pair/c any/c))))])))])))
(module mylist2-with-contracts mzscheme
(define mycons cons)
(define myempty '())
(define mycar car)
(require list-signature-with-contracts)
(provide-list-operations-with-contracts))
(require mylist2-with-contracts)
(mycons 1 2)
But I keep getting the error:
reference to undefined identifier: mycons
--
Jens Axel Søgaard