Search code examples
c#.netironscheme

Resetting IronScheme Engine in C#


Is there a way to "reset" the IronScheme engine? I'm essentially aiming to ensure that successive calls to string.Eval() are executed independently.

For example, I want to be execute

"(define x 1.0) (+ x 5.0)".Eval()

then reset, and have the call

"(+ x 3.0)".Eval()

fail as it would if it were executed by itself.

Even better would be a way to give each of n concurrent threads its own independent space in which to execute.


Solution

  • You have 2 options for the REPL (with libraries it will not even allow you to write such code ;p).

    1: Reset the interaction environment.

    This can be done with (interaction-environment (new-interaction-environment)).

    Sample:

    > (define x 5) (+ x 5)
    10
    > (interaction-environment (new-interaction-environment))
    > (+ x 5)
    Unhandled exception during evaluation:
    &undefined
    &message: "attempted to use undefined symbol"
    &irritants: (x)
    

    2: Create a new interaction environment that you hold on to in C#.

    If you want to concurrent environments, this is probably the best option. I use this approach for the IronScheme online evaluator.

    Sample:

    "(define x 1.0) (+ x 5.0)".Eval();
    var env = "(new-interaction-environment)".Eval();
    "(+ x 3.0)".EvalWithEnvironment(env);
    

    Possible solution:

    Func<object> reset = 
       "(lambda () (interaction-environment (new-interaction-environment)))".
       Eval<Callable>().Call;
    
    "(define x 1.0) (+ x 5.0)".Eval();
    
    reset();
    
    "(+ x 5.0)".Eval();