Is it possible to use other #lang
s in #lang scribble/lp
for literate programming?
For example, I want to use #lang typed/racket
in #lang scribble/lp
. How to realize that?
Is it possible to use other #lang
s in #lang scribble/lp
for literate programming?
For example, I want to use #lang typed/racket
in #lang scribble/lp
. How to realize that?
TL;DR: There are two ways. First, you can simply put your code in a submodule, and require it immediately. Second, you can use my fork of scribble/lp2
, which allows you to specify the underlying module language.
Due to an issue, you'll have to wrap the whole thing in a (begin …)
, although there's a pull request which should fix this on the way.
#lang scribble/lp2
@chunk[<*>
(begin
(module main typed/racket
(define a : Number 1)
(provide a)
(module moo racket/base '…)
(module+ test
(require typed/rackunit)
(check-equal? a (+ 1/2 1/2))))
(require 'main)
(provide (all-from-out 'main))
(module test typed/racket
(require (submod ".." main test))))]
Bear in mind that these are submodule, so you can't put your test
module inside main
, as it won't be executed. Here, I have a (module+ test …)
inside main
, and it is required by a test
module at the root level. If the (module test
at the root is commented out, then the tests won't be executed.
The same concern applies also when requiring moo
from another module, you'll have to use (require (submod "myfile.lp2.typed.rkt" main moo))
, or make an "alias" like is done above for test
and main
.
Keep also in mind that the more nested a submodule is, the more times it gets visited and/or instantiated (not sure which). This can have a serious impact on the loading speed in typed/racket programs, as they are already themselves visited and/or instantiated multiple times. You can see this by adding (begin-for-syntax (displayln 'executed))
in your code, it gets printed many times.
My fork of scribble/lp2
, hyper-literate (for hypertext literate programming) only alters scribble/lp2
and relies on the original version of scribble
for the rest.
I don't guarantee backwards compatibility, as I'm currently fixing some bugs and adding extra features like being able to re-print a chunk
to refresh the reader's memory, etc. The stackoverflow-q-18877881
branch I linked to should remain stable, though. Newer stuff will go in master
.
Here's a small example file. There's a more complete example in test/test.hl.rkt
:
#lang hyper-literate/typed typed/racket/base
@(require (for-label typed/racket/base
typed/rackunit))
@title{Title}
Hello world.
@chunk[<*>
(require typed/rackunit)
;; Would give an error as typed/racket/base is used on the #lang line:
;curry
(check-equal? ((make-predicate One) 1) #t)
(define (f [x : 'e123]) x)
(define ee (ann (f 'e123) 'e123))
(provide ee)]
It doesn't appear so, but you can use a typed/racket evaluator with scribble/eval.
#lang scribble/manual
@(require racket/sandbox
scribble/eval)
@(define my-evaluator
(parameterize ([sandbox-output 'string]
[sandbox-error-output 'string])
(make-evaluator 'typed/racket/base)))
@interaction[#:eval my-evaluator
(: my-sqr (Real -> Real))
(define (my-sqr x)
(* x x))
(my-sqr 42)]
Example taken from here.