[plt-scheme] Problem with macro generated provide/contract

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Nov 5 21:44:24 EST 2005

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.

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:

    (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'.

Matthew



Posted on the users mailing list.