degrees of runtime metaprogrammability
"runtime metaprogrammability" describes the ability for a program to create new pieces of code as it is running, ideally of the same class as its initial code.
various computational frameworks have various expectations as to how much of a given program's logic possesses runtime metaprogrammability. frameworks with bad metaprogrammability, when encoding new logic, are forced to embed interpreted sub-languages.
- machine codes (x86, RISC-V, ARM etc…) have pretty good metaprogrammability: a program in x86 can just write to a buffer bytes representing new x86 code, and then jump into that code. note that simpler instruction sets (such as RISC-V) make it easier to produce new code.
- WASM has bad metaprogrammability: no WASM interpreter or compiler that i know of lets a function create a new function as the same class as those described in the original module. programs can create new WASM modules and, if they're lucky enough to be ran in an environment that provides functions that allow the loading of new modules, can get linked with than new code this way, but this is far from ideal nor standard.
- the JVM lets pieces of bytecode create new bytecode; while i don't think this is utilized in java, it's a notable feature of clojure which lets it compile newly defined functions.
- turing machines have relatively bad metaprogrammability: most of the logic of a given turing machine is expected to reside in its ruleset, which is immutable. to embed new logic, a ruleset would need to embed an interpreter for some type of other code described in its ruleset.
- SKI calculus and λ-calculus probably have somewhat good metaprogrammability; though it's not exactly clear to what extent. i believe new expressions will always be built out of skeletons of original expressions, but a seamless third party could probably move in and replace most expressions with newly "compiled" functions.
- cellular automata generally have fairly good metaprogrammability; rules like rule 30 or conway have simple enough rules that most of the logic of any complex system probably resides at the cell level rather than in the ruleset.
- graph rewriting, notably wolfram's hypergraph rewriting rules, seem to offer fairly bad metaprogrammability; the ability for rules to produce new rules would require encoding most of the logic of a given system as graphs themselves with a relatively simple top-level actual set of hard rules, which seems difficult especially in the case of hypergraphs when rules are expected to be able to apply to an arbitrary amount of arguments.