If you don’t care about syntactic convenience, yes. In practice, a(n idiomatic) Forth “library” can have an API like, for example,
1000 ,bp) ax mov,
for laying down assembly code in memory (might look a bit unusual, but think “postfix assembler” and it’ll become natural soon enough). If you want this to compile down to byte writes and arithmetic without requiring an assembler library at runtime (DynASM-style), you can do that as well.
Custom control structures[1], object systems, perfect hashing, parser generators, all that fun stuff that’s possible with flexible syntax and arbitrary compile-time code execution, people have done it. You never have to think whether an X-macro is sufficiently ugly yet to warrant a custom preprocessor. (If you want to say “web templating”, you can say “web templating”, except it’s not that pleasant with manual memory management, and most of what I’m thinking about was written in the 80s.)
There’s nothing impossible about this in any language (the absence of a competent C REPL continues to amaze me), but not all languages are good at everything they can technically do, and Forth is good at these.
(Forth is also bad at some things. If you want code that transparently works on floats and doubles, or 32- and 64-bit addresses, on the same system depending on a compile-time setting, it’s going to be painful. Passing abstract types by value is impossible to do elegantly as far as I know. Omitting unnecessary code from the executable, trivial with static libraries and a linker, requires adapting half your implementation and is a serious selling point for commercial Forth systems. And so on.)
[1] I know we’re all alleged adults and are not supposed to get excited about these, but does LuaJIT’s FOLD tree peephole optimizer, for example, qualify as a legitimate custom control structure? (It’s implemented with a combination of macro magic and a custom preprocessor.)
Custom control structures[1], object systems, perfect hashing, parser generators, all that fun stuff that’s possible with flexible syntax and arbitrary compile-time code execution, people have done it. You never have to think whether an X-macro is sufficiently ugly yet to warrant a custom preprocessor. (If you want to say “web templating”, you can say “web templating”, except it’s not that pleasant with manual memory management, and most of what I’m thinking about was written in the 80s.)
There’s nothing impossible about this in any language (the absence of a competent C REPL continues to amaze me), but not all languages are good at everything they can technically do, and Forth is good at these.
(Forth is also bad at some things. If you want code that transparently works on floats and doubles, or 32- and 64-bit addresses, on the same system depending on a compile-time setting, it’s going to be painful. Passing abstract types by value is impossible to do elegantly as far as I know. Omitting unnecessary code from the executable, trivial with static libraries and a linker, requires adapting half your implementation and is a serious selling point for commercial Forth systems. And so on.)
[1] I know we’re all alleged adults and are not supposed to get excited about these, but does LuaJIT’s FOLD tree peephole optimizer, for example, qualify as a legitimate custom control structure? (It’s implemented with a combination of macro magic and a custom preprocessor.)