[racket] Fresh sandboxes in Scribble documentation

From: Neil Toronto (neil.toronto at gmail.com)
Date: Sat Nov 20 12:06:52 EST 2010

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
                 (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

Posted on the users mailing list.