[racket] Add an implicit (require (for-doc ...)) via a #lang

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Dec 6 14:01:52 EST 2013

It would be nice if `(provide (for-doc ...))` worked. I'm not sure
offhand how to do that.

Meanwhile, the problem with your implementation is that a
macro-introduced `require` does not bind identifiers in the context of
the use. You need a non-hygienic `#%module-begin` to give imported
identifiers the lexical context of the macro use.

Like this:

 (require (for-syntax racket/base))

 (define-syntax (module-begin stx)
   (syntax-case stx ()
     [(_ a ...)
      (with-syntax ([racket/base (datum->syntax stx 'racket/base)]
                    [scribble/manual (datum->syntax stx 'scribble/manual)])
        #'(#%module-begin
           (require
            (for-doc
             racket/base
             scribble/manual))
           a
           ...))]))


At Thu, 5 Dec 2013 16:21:25 -0700, Michael Ballantyne wrote:
> Hello all,
> I'm implementing a module language. All modules using the language
> will be using Scribble's in-source documentation. It's easy enough to
> have the module language provide
> 
> (all-from-out racket/contract scribble/srcdoc)
> 
> but I haven't figured out a way to avoid having each module have the lines
> 
> (require (for-doc racket/base
>           scribble/manual))
> 
> One thing I've tried is adding that require form to the top of modules
> using the language via #%module-begin. The code I used for that is
> below:
> 
> #lang racket/base
> 
> (require
>  racket/contract
>  scribble/srcdoc
>  scribble/manual
>  )
> 
> (provide
>  (except-out (all-from-out racket/base) #%module-begin)
>  (rename-out
>   [module-begin #%module-begin])
>  (all-from-out
>   racket/contract
>   scribble/srcdoc)
>  )
> 
> (module reader syntax/module-reader
>   #:language 'doctest)
> 
> (define-syntax-rule (module-begin a ...)
>   (#%module-begin
>    (require
>     (for-doc
>      racket/base
>      scribble/manual))
>    a
>    ...
>    )
>   )
> 
> Then testing with this file:
> 
> #lang at-exp doctest
> 
> (define (testfun a)
>   a)
> 
> (provide
>  (proc-doc/names
>   testfun
>   (-> any/c any/c)
>   (a)
>   @{Doc test}
>   )
>  )
> 
> I receive this error:
> 
> ?: literal data is not allowed;
>  no #%datum syntax transformer is bound in: "Doc test"
> 
> Examination with the macro stepper in Dr. Racket suggests the
> module-begin syntax rule is working as expected, but the (require
> (for-doc ...)) that is added somehow doesn't behave like one that was
> originally the module does.
> 
> Any ideas on what might be going wrong or on a better way to achieve this?
> 
> Thanks!
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.