[racket] Fresh sandboxes in Scribble documentation (was: Typed macros in untyped code)
Sam Tobin-Hochstadt wrote:
> On Thu, Nov 18, 2010 at 7:48 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> But Typed Racket craps on me if I use the typed macros inside a sandbox in
>> Scribble. For example, using @(example #:eval my-eval (bftest-error (bfexp
>> (bf 2)))) gives me this:
>>
>>> (bftest-error (bfexp (bf 2)))
>> eval:63:0: Type Checker: Macro bftest-error from typed
>> module used in untyped code in: (bftest-error (bfexp (bf
>> 2)))
>>
>> Gah! I thought I got around this! How do I convince Typed Racket or the
>> sandbox that I'm not up to anything funny?
>
> Require `#%top-interaction' from typed racket, or in general create
> your sandbox from Typed Racket.
Okay, I got that working by copying from ts-guide.scrbl. I like having
the types printed in the examples. Nice.
Now I have another problem: I can't redefine anything inside the
sandbox. I use consistent names for the same types of objects, so this
is a problem from a pedagogical point of view.
But it's not TR's fault, hence the subject change. By disallowing
redefinition, TR is actually exposing a problem in how we usually write
documentation that contains examples.
The problem: because we create one evaluator and use it for everything,
our documentation examples aren't independent. They can change each
other's execution environments. Anything that has a computational effect
can do that: using set!, setting parameters, or even *defining a variable*.
All of my examples set a parameter. If I used `parameterize' instead,
they'd all look like this:
@(examples #:eval bigfloat-eval
(parameterize ([bf-bits ...])
<some-computation>)
(parameterize ([bf-bits ...])
<some-computation>)
...)
I can't combine them all under one `parameterize' because I'd lose the
REPL-like interaction. But as it is, I can't reorder my examples or
`defproc's without thinking seriously about the effect they'll have on
each other.
So I tried to solve the independent-examples problem by creating a fresh
evaluator for each example. When I tried to run it, it took forever. And
then it ran out of memory and DrRacket asked for more.
Currently, I only create a new evaluator for *specific* examples that
have certain effects, but this won't scale. Question for the group: is
there a better way to isolate examples? I've got a voodoo half-idea that
I can branch the original evaluator using continuations, but I don't
know how.
Neil T