> For example, in CL debugging, how would I reliably set a breakpoint at some nested expression in a function body, run to it, and step through the code "expr-by-expr" while verifying a bunch of values in a watch window?
I ... don't ever do this when debugging lisp? Sly has support for setting breakpoints, but I'm used to adding (break) expressions; the "breakdot on the side" doesn't work as well with Lisp as C (With idiomatic C you very rarely want to set a breakpoint in the middle of a line, and it's rare for a single statement to be more than 2-ish lines; I should also note that IIRC setting breakpoints in the middle of a line in VS was not the best UX).
Sly has a keyboard shortcut for stepping, but I don't have it memorized because I hardly ever use it. Conversely its F10/F11 in VS, which I still remember despite not having used Visual Studio for at least a decade, since I did it a lot!
Conversely, I have the shortcuts for recompile the single file I'm in and recompile the single function I'm in memorized, since I use those all the time when debugging. I believe VS added hot-patching functions at some point near the end of my usage, but it wasn't part of my workflow like it is with Lisp.
(The lack of) watch windows is a deficiency in Sly. While you can view all locals in the current stack-frame while debugging, it doesn't let you watch arbitrary expressions, and if you have too many locals it can be hard to focus on what you want.
I should point out stickers (C-c C-s C-s) let you trace evaluations of arbitrary subexpressions, and this has some overlap with how watchpoints are used in VS.