Typescript's union types are really nice for writing interpreters.
type Value = NumberValue | StringValue;
function add(array<Value> args): NumberValue { ... }
I often find that primitive functions get little checking (e.g. just returning a Value) in the host language.
miniblog.
Related Posts
TIL Tcl has a notion of 'safe interpreters', a mode where you can run untrusted code in a sandbox: https://www.tcl.tk/man/tcl8.4/TclCmd/safe.htm
Not many programming languages have this, but it's way safer to include in the implementation than try to build as a userland library.
Implementing interactive languages, and the tradeoffs of interpreters, JIT compilers, and AOT compilers:
On storing ASTs in flat arrays for performance, and the relationship with bytecode interpreters: