3
votes

The R7RS report on the programming language Scheme describes two ways of running Scheme code in a Scheme system:

1) A scheme system can run a program as described in section 5.1 in the report.

2) A scheme system can offer a read-eval-print-loop, in which Scheme code is interpreted interactively.

My question is on how these two ways of running Scheme code can be reflected inside a Scheme system with what's included in the R7RS report.

There is the eval library procedure eval, which executes Scheme code inside a running Scheme system so eval looks like what I am searching for.

However, the only guaranteed mutable environment I can plug in eval is the environment returned by the interaction-environment repl library procedure. With this, however, I cannot reliably simulate a REPL (point 2) from above) because a REPL allows the import form, which the eval procedure does not have to.

Also, I cannot use the interaction environment for evaling a full Scheme program by other reasons: It is generally not empty, in particular it contains all bindings of (scheme base).

For realising 1) inside a running Scheme system, the eval library procedure environment looks promising as it allows to import libraries beforehand (which is part of running programs). However, the environment is immutable, so I cannot evaluate defines inside the environment. A way out would be to wrap the body of the program to be run in a lambda form so that define would define local variables. However, this also doesn't work: Inside a lambda form all defines have to come at the beginning of the body (which is not true for the top-level of a Scheme program) and inside a lambda form library bindings can be lexically overwritten, which is not possible by top-level bindings.

As Scheme is Turing-complete, I can, of course, simulate a Scheme system inside a running Scheme system but I am wondering whether it is possible just by using the eval procedure. One reason for my interest is that eval might be optimized (e.g. by a JIT compiler backend), so using this procedure might give near native speed (compared to writing a simple interpreter by hand).

1
import declarations can be translated into an equivalent load in an implementation-specific way. Also you can just load a file that contains the user-entered REPL expressions. Personally I'd just try to eval the import declaration directly, but as you said, that's not totally portable, and quite possibly, nothing is. I guess REPLs are generally implementation-specific for a reason. (Disclosure: I do not believe Scheme portability is realistic.)Chris Jester-Young

1 Answers

6
votes

R7RS-small is not intended for this sort of reflective implementation. R7RS-large will provide a library that supports user-created mutable environments.