[plt-scheme] Testing procedures using local-expand

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Wed Apr 29 11:51:12 EDT 2009

Noel Welsh wrote:
> Hello,
> 
> I'm trying to test a function the uses local-expand. This is somewhat
> difficult, as I can't use local-expand outside of a transformer, so I
> have to do some hoops to setup a transformer etc. Anyway, I'm getting
> an error from my test:
> 
>   unet-util-test.ss:8:10: define-syntaxes: bad syntax in:
> (define-syntaxes (foo) (syntax-rules () ((foo x) (define x 1))))
> 
> This is a perfectly fine expression (I can paste it into a REPL and it
> works). So can anyone enlighten me on what is going on?  Code is
> below.

That doesn't necessarily mean that the term is bad, just that it doesn't 
match any clause of some 'syntax-case' expression.

> First, the function under tests:
> 
> ;; sort-exprs : (stx-listof stx) -> (values (listof expr) (listof expr))
> ;;
> ;; Sort a list of syntax into a list of transformer
> ;; definitions and a list of other expressions
> (define (sort-exprs exprs)
>   (let loop ([exprs exprs]
>              [transformers null]
>              [expressions null])
>     (if (null? exprs)
>         (values transformers expressions)
>         (let ([stx (stx-car exprs)]
>               [rest (stx-cdr exprs)])
>           (kernel-syntax-case
>            (local-expand stx 'module (kernel-form-identifier-list))
>            #f
>            [(define-syntaxes (id ...) body ...)
>             (loop rest (cons stx transformers) expressions)]
>            [(define-values (id ...) body ...)
>             (loop rest transformers (cons stx expressions))])))))
> 
> The test harness:
> 
> (define-for-syntax exprs
>   (list #'(define-syntax foo
>             (syntax-rules ()
>               [(foo x) (define x 1)]))
>         #'(define (bar x)
>           (+ x 1))))
> 
> (define-syntax (sort stx)
>   (syntax-case stx ()
>     [(sort)
>      (with-syntax ([(transformers expressions) (sort-exprs exprs)])
>        (syntax (list (quote-syntax transformers)
>                      (quote-syntax expressions))))]))

This works for me, if I wrap a 'begin-for-syntax' around the definition 
of 'sort-exprs' above (and add requires for-syntax of syntax/stx and 
syntax/kerncase and change 'values' to 'list').

If you're putting 'sort-exprs' in another module and requiring it 
for-syntax, you need to add
   (require (for-template scheme/base))
to the module; otherwise, it won't have the right bindings for 
'define-values' and 'define-syntaxes', and the literals won't match. 
Omitting that require gives you the error you reported above.

Ryan


Posted on the users mailing list.