Does it? Asking for a value when encountering an unbound variable is a default restart
$ sbcl
This is SBCL 2.1.1.52.HEAD.321-f8a57bcca, an
implementation of ANSI Common Lisp.
More information about SBCL is available at
<http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
\* (\* x x)
debugger invoked on a UNBOUND-VARIABLE in thread
#<THREAD "main thread" RUNNING {1001860103}>:
The variable X is unbound.
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE ] Retry using X.
1: [USE-VALUE ] Use specified value.
2: [STORE-VALUE] Set specified value and use it.
3: [ABORT ] Exit debugger, returning to top level.
(SB-INT:SIMPLE-EVAL-IN-LEXENV X #<NULL-LEXENV>)
I suspect you are right.
Rebinding an inner function inside another function that contains variables probably will not work.
But you could still alter and rebind the entire thing.
And that is still flexible; you can still change a running program on the fly with only that ability.
And you can always reference objects at the top level.
Smalltalk famously let you code inside the debugger.
You can run code with methods that don't exist yet and add them in the debugger when it notices they are missing.
You can use a REPL powered debugger. You can interact with the debugger to a higher degree than with most mainstream languages. It’s not quite as powerful as CL though, from what I’ve read.
Or you pull out expressions and test them in isolation with given (assumed) inputs.