[plt-scheme] Macro contracts (feature request)

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Aug 10 17:33:23 EDT 2007


Ryan's dissertation -- with the working thesis of "Scheme macros lack  
conventional software develop support; I am constructing some" --  
will introduce some of these things soon. -- Matthias



On Aug 10, 2007, at 5:03 PM, David Van Horn wrote:

> Macro definitions are often obfuscated by interleaving code to  
> detect and report errors in the use of the macro.  The same can be  
> true of procedures, but fortunately the contract mechanism lets you  
> write procedures based on the assumptions stated in a contract.  It  
> would be useful to write macros in a similar way.
>
> For example, if I write the usual swap! macro:
>
>   (define-syntax swap!
>     (syntax-rules ()
>       ((swap! x y)
>        (let ((tmp y))
>          (set! y x)
>          (set! x tmp)))))
>
> I'd like to be able to attach the following contract to the  
> transformer procedure:
>
>    (-> (and/c (syntax/c
>                 (list/c identifier? identifier? identifier?))
>               (lambda (stx)
>                 (with-syntax (((swap! x y) stx))
>                   (not (bound-identifier=? #'x #'y)))))
>        (syntax/c any/c))
>
> Ideally, I could write (provide/contract [swap! ---]) with the  
> above contract.  The contract system would, seeing that swap! is a  
> macro, attach the RHS to the transformer value.  But as far as I  
> can tell, there is no way to do this currently.
>
> I can fake it as follows:
>
> (module m-syntax mzscheme
>   (require (lib "contract.ss"))
>   (require-for-template mzscheme)
>
>   (provide/contract
>    [swap!-procedure  ;; shape contract for swap!.
>     (-> (and/c (syntax/c
>                 (list/c identifier? identifier? identifier?))
>                (lambda (stx)
>                  (with-syntax (((swap! x y) stx))
>                    (not (bound-identifier=? #'x #'y)))))
>         (syntax/c any/c))])
>
>   (define swap!-procedure
>     (syntax-rules ()
>       ((swap! x y)
>        (let ((tmp y))
>          (set! y x)
>          (set! x tmp))))))
>
> (module m mzscheme
>   (provide swap!)
>   (require-for-syntax m-syntax)
>   (define-syntax swap! swap!-procedure))
>
> But this sort of thing should be easier.  Also, this gets the blame  
> wrong: (swap! x x) will blame m rather than the top-level where the  
> malformed expression occurs.
>
> David
>
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.