I think ideally I'd like both capabilities, which seems possible if you just expose the language's parser as a function.
I think ideally I'd like both capabilities, which seems possible if you just expose the language's parser as a function.
That, along with the ability to pass code block literals, lets you redefine the language into your own DSL with new control flow statements. You can define a “while loop” function, for example.
Before heavy use of closures and callbacks in dynamic languages (Array.forEach, for example) became the thing this was pretty huge, and it’s still nicer syntax sugar than you get defining control structures with that route.
I used TCL with Squish for Qt-based UI test automation for a couple of years. For stuff like that where you really do want a set of domain-specific imperatives you can string together, it was really cool to work with. Biggest downside was you could get too fancy and find yourself alone off in the weeds of your own DSL.
Plus things like uplevel let you jam a lot of meta trickery into commands without needing AST manipulation.
So, yeah, you do get both capabilities, it's just done atop the very simple baseline system, if that makes sense.
(look at e.g. 'snit', a pure Tcl OO system, as an example of what can be done with just Tcl itself)