[plt-scheme] Macro contracts (feature request)

From: David Van Horn (dvanhorn at cs.brandeis.edu)
Date: Fri Aug 10 17:03:36 EDT 2007

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



Posted on the users mailing list.