[racket] module+ test... (require rackunit) results in unbound identifier when used in macro

From: Scott Klarenbach (scott at pointyhat.ca)
Date: Wed Jan 8 18:44:15 EST 2014

Thanks guys.

I changed it to this:

(define-syntax (define/test stx)
  (syntax-parse stx
[(_ (proc:id arg:expr ...)
body:expr ...
#:test test-body:expr ...)
 (with-syntax ([id-str (symbol->string (syntax->datum #'proc))]
[ru-require (format-id stx "~a" "rackunit")])
   #'(begin
   (define (proc arg ...) body ...)
   (module+ test
 (require ru-require)
 (test-case id-str test-body ...))))]))

and it works now.  Is that what you meant Carl?

The problem is that check-true (and check-false) are not in scope (as
> you discovered) during expansion.


I'm still a bit confused as to why.  I figured the (require rackunit) would
have brought check-true into scope during expansion, much the same as if I
just copied the (begin... form into another file without the macro.



On Wed, Jan 8, 2014 at 2:37 PM, Carl Eastlund <carl.eastlund at gmail.com>wrote:

> I do not suggest rebinding the whole body like that; it could be seriously
> problematic if the user refers to something not viable to the macro
> definition.  What you need to rebind is the name "rackunit" itself passed
> to require so that it has the context of the macro application.  That way
> the names bound by the require will be visible to the macro user.
> On Jan 8, 2014 5:29 PM, "Stephen Chang" <stchang at ccs.neu.edu> wrote:
>
>> The problem is that check-true (and check-false) are not in scope (as
>> you discovered) during expansion. Here is one way to fix your problem
>> by recapturing the test expressions to have the proper context. You
>> can also use syntax-local-introduce instead of the lambda (someone
>> correct me if this is not proper usage).
>>
>> #lang racket
>> (require (for-syntax syntax/parse))
>>
>> (define-syntax (define/test stx)
>>   (syntax-parse stx
>>     [(_ (id arg ...) body ... #:test test-body ...)
>>      (with-syntax ([id-str (symbol->string (syntax->datum #'id))]
>>                    [(new-test-body ...)
>>                     (map
>>                      (λ (s) (datum->syntax #'here (syntax->datum s)))
>>                      (syntax->list #'(test-body ...)))])
>>        #'(begin
>>            (define (id arg ...) body ...)
>>            (print id-str)
>>            (module+ test
>>              (require rackunit)
>>              (test-case id-str
>>                         new-test-body ...))))]))
>>
>> (define/test (my-fn a b c)
>>   (print a)
>>   (print b)
>>   (print c)
>>   #:test
>>   (check-true #t)
>>   (check-false #t))
>>
>> On Wed, Jan 8, 2014 at 4:53 PM, Scott Klarenbach <scott at pointyhat.ca>
>> wrote:
>> > I have the following macro:
>> >
>> > (define-syntax (define/test stx)
>> >   (syntax-parse stx
>> > [(_ (id arg ...) body ... #:test test-body ...)
>> > (with-syntax ([id-str (symbol->string (syntax->datum #'id))])
>> >   #'(begin
>> >   (define (id arg ...) body ...)
>> >   (print id-str)
>> >   (module+ test
>> > (require rackunit)
>> > (test-case id-str
>> >   test-body ...))))]))
>> >
>> > Which handles some testing boilerplate and allows me to use it like so:
>> >
>> > (define/test (my-fn a b c)
>> >   (print a)
>> >   (print b)
>> >   (print c)
>> >   #:test
>> >   (check-true #t)
>> >   (check-false #t))
>> >
>> > The problem is that the (require rackunit) expression inside of (module+
>> > test) is not being picked up after macro expansion.  Running either the
>> code
>> > or the tests (via raco test) results in: unbound identifier check-true.
>> >
>> > Adding (module+ (require rackunit)) to the top of the file solves the
>> > problem and both the file and tests run as expected.
>> >
>> > What am I missing?
>> >
>> > Thanks.
>> > --
>> > Talk to you soon,
>> >
>> > Scott Klarenbach
>> >
>> > PointyHat Software Corp.
>> > www.pointyhat.ca
>> > p 604-568-4280
>> > e scott at pointyhat.ca
>> > 200-1575 W. Georgia
>> > Vancouver, BC V6G2V3
>> >
>> > _______________________________________
>> > To iterate is human; to recur, divine
>> >
>> > ____________________
>> >   Racket Users list:
>> >   http://lists.racket-lang.org/users
>> >
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>
>


-- 
Talk to you soon,

Scott Klarenbach

PointyHat Software Corp.
www.pointyhat.ca
p 604-568-4280
e scott at pointyhat.ca
200-1575 W. Georgia
Vancouver, BC V6G2V3

_______________________________________
To iterate is human; to recur, divine
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140108/5c75afe8/attachment.html>

Posted on the users mailing list.