Alex Shroyer
Alex Shroyer

Reputation: 3829

How to require inside a Racket macro?

I currently am putting unit tests at the bottom of the file I'm working on, like this:

(provide foo)
(define (bar x) (+ 1 x))

;; unit tests
(module+ test
  (require racket/pretty)
  (define testcases '(2 3 4))
  (for ([test testcases])
    (pretty-print (bar test))))

This works, but I want to avoid repeating the boilerplate unit test code for all my modules. Having never written a macro in Racket before, I'm unsure how to get the various parts to fit together.

I would like to have the following code expand to the boilerplate version above:

(provide foo)
(define (bar x) (+ 1 x))

;; unit tests
(test foo '(2 3 4))

Upvotes: 1

Views: 80

Answers (1)

Alex Knauth
Alex Knauth

Reputation: 8373

For the test macro, are you sure you need to generate a require from the macro? You can have the test macro generate a use of pretty-print if racket/pretty is required in the file that defines test, and then it doesn't matter whether there's a require in the file that uses test.

For example if you have two files macro.rkt and use.rkt:

file macro.rkt:

#lang racket
(provide test)
(require racket/pretty
         syntax/parse/define)

(define-simple-macro (test fn:id args:expr)
  (module+ test
    (define testcases args)
    (for ([test testcases])
      (pretty-print (fn test)))))

file use.rkt:

#lang racket
(require "macro.rkt")
(provide foo)
(define (foo x) (+ 1 x))

;; unit tests
(test foo '(2 3 4))

Then the reference to pretty-print works in the output of the macro even though it's not normally available in use.rkt. It works because pretty-print gets its scope from the macro definition site, not the use site.

Does this work for your problem?

Upvotes: 4

Related Questions