[racket] Fresh sandboxes in Scribble documentation
Eli Barzilay wrote:
> *snipped a bunch of interesting ideas*
I finally have a solution: fake Typed Racket into allowing redefinitions
by alpha-renaming everything defined at the top level.
It's easier than it sounds. Here's the macro:
(define-syntax (maybe-rename stx)
(syntax-case stx ()
[(_ e)
(let ([expanded (local-expand #'e (syntax-local-context) #f)])
(syntax-case expanded (define-values)
[(define-values (x ...) expr)
(with-syntax ([(y ...) (generate-temporaries #'(x ...))])
(syntax/loc stx
(begin
(define-syntax x (make-rename-transformer #'y)) ...
(define-values (y ...) expr))))]
[_ #'e]))]))
It leaves every non-define form unchanged, and turns (maybe-rename
(define x 5)) into
(begin (define-syntax x (make-rename-transformer #'x1))
(define-values (x1) 5))
TR doesn't care if you redefine syntax bindings, so following that with
(maybe-rename (define x 10)) effectively shadows the previous definition
of `x' and passes the type check.
It's not truly equivalent to the untyped REPL. You can't replace
definitions, which the untyped REPL allows. But `set!' will let you do
that. Also, it doesn't handle recursive functions, though it seems it
*should* because all the names match up in the macro stepper. :/
Anyway, I made an evaluator that requires `maybe-rename' and composed
the evaluator with a lambda that wraps expressions with `maybe-rename'
and passes messages through. My compiles went from 2:50 with a handful
of evaluators to 0:55 with just one.
I would like to have something like this in the TR REPL itself.
Neil T