eval("rate + 1", env) with rate bound to 3 in env should mean 4. In compile-time mode, in runtime mode, every time. Flip a mutable host global called rate to 9 and the meaning of that input should not move.
That's the rule I want for this experimental D evaluator, so the environment is always an argument, even though a global lookup would make the first example shorter. D already leans this way. It evaluates eligible functions where a compile-time value is required, and CTFE code can't reference mutable globals or statics. Nice pressure test. That promise is narrower than it looks, though. Not every function can run under CTFE, and CTFE is no general security sandbox.
The host pays for it by assembling and passing every binding it wants the evaluator to see. In return, the same expression with the same environment means the same thing in both modes.
If rate is missing, no quiet fallback to the host global. Rejected. A runtime recovery hook could come later, and its docs would need to say whether a supplied replacement becomes part of the evaluation input.
