Using scribble/srcdoc with at-exp reader allows you to write module documentation within the provide form ensuring all the provided symbols are somehow (preferably properly) documented. In certain situations, you want to include the actual values of the symbols you provide or values used for computation when the symbol is a procedure or syntax form. I use this approach in uni-table documentation[1] to make sure the documentation lists all valid color names and other things as they are used in the module itself.
Here's a minimal example of a module for-doc-test1.rkt
using scribble/srcdoc for providing the documentation of provided procedure:
#lang at-exp racket/base
(require scribble/srcdoc
(for-doc scribble/manual
racket/base
(submod ".." my-constants)
)
racket/contract)
(provide
(proc-doc
return-a-number
(-> number?)
@{
Returns @racket[a-number]: @racket[#,a-number].
}))
(module my-constants racket/base
(provide a-number)
(define a-number 1) )
(require 'my-constants)
(define (return-a-number)
a-number)
In order to render the documentation, a small for-doc-test1.scrbl
file may read:
#lang scribble/manual
@require[scribble/extract]
@title{for-doc test 1}
@defmodule[for-doc-test1]
@include-extracted["for-doc-test1.rkt"]
Creating the documentation is then just a matter of running scribble for-doc-test1.scrbl
and it generates a nice HTML documentation which properly states "Returns a-number: 1." in the procedure description.
If you use this module in a program it works like charm. Take the following ```for-doc-test1-usage.rkt" as an example:
#lang at-exp racket/base
(require "for-doc-test1.rkt")
(define (test-a-number)
(displayln (return-a-number)))
(module+ main
(test-a-number))
This program can be run using racket for-doc-test1-usage.rkt
, it can be compiled using raco make for-doc-test1-usage.rkt
and no problems show up.
However if the usage program is a module that is intended to be used elsewhere and scribble/srcdoc provides are present, something strange happens. The updated usage example is as follows:
#lang at-exp racket/base
(require scribble/srcdoc
(for-doc scribble/manual
racket/base)
"for-doc-test1.rkt"
racket/contract)
(provide
(proc-doc
test-a-number
(-> void?)
@{
Prints a-number.
}))
(define (test-a-number)
(displayln (return-a-number)))
(module+ main
(test-a-number))
Trying to run this program yields:
car: contract violation
expected: pair?
given: #<path:/home/joe/Projects/Programming/uni-table/for-doc/..>
context...:
/usr/share/racket/collects/racket/require-transform.rkt:190:2: convert-relative-module-path
/usr/share/racket/collects/racket/private/reqprov.rkt:72:2: check-lib-form
/usr/share/racket/collects/racket/private/reqprov.rkt:80:13: t
/usr/share/racket/collects/racket/require-transform.rkt:266:2: expand-import
/usr/share/racket/collects/racket/private/reqprov.rkt:607:22
/usr/share/racket/collects/racket/private/reqprov.rkt:603:5
/usr/share/racket/collects/racket/require-transform.rkt:266:2: expand-import
[repeats 1 more time]
/usr/share/racket/collects/racket/private/reqprov.rkt:285:21: try-next
/usr/share/racket/collects/racket/private/reqprov.rkt:256:2
/usr/share/racket/collects/syntax/wrap-modbeg.rkt:46:4
Of course, trying to compile it produces the same result. I found a rather simple workaround, just remove the submod from the for-doc form and use begin-for-doc. The updated module then looks like this:
#lang at-exp racket/base
(require scribble/srcdoc
(for-doc scribble/manual
racket/base)
racket/contract)
(begin-for-doc
(require (submod ".." my-constants)))
(provide
(proc-doc
return-a-number
(-> number?)
@{
Returns @racket[a-number]: @racket[#,a-number].
}))
(module my-constants racket/base
(provide a-number)
(define a-number 1))
(require 'my-constants)
(define (return-a-number)
a-number)
Now it compiles and runs fine - that's what I actually used in affected module of uni-table[2].
The question is: is there something missing in my understanding of how require subforms (for-doc especially) work or is it a bug in Racket?
[1] https://docs.racket-lang.org/uni-table/Styles.html#(part._.S.G.R_.Styles)
[2] https://gitlab.com/racketeer/uni-table/-/blob/master/private/sgr-style.rkt