39 ms·
> This is a common complaint about CL, but my experience is that the utility of debuggers is vastly over-stated. It is possible to patch a running CL system by
by jonathankoren 3y ago
> This is a common complaint about CL, but my experience is that the utility of debuggers is vastly over-stated.
It is possible to patch a running CL system by simply setting a breakpoint and then revaluating a function.
I am unaware of any other language that is possible in.
This Lisp feature is only made possible through a debugger.
I know, because I've done it.
- _19qg 3y ago> It is possible to patch a running CL system by simply setting a breakpoint and then revaluating a function. It's also possible to change a running CL system without setting a breakpoint and/or re-evaluating a function. > I am unaware of any other language that is possible in. Start with Smalltalk and then search for more.
- fiddlerwoaroof 3y agoYeah, although the debugger in lisp is also lacking a lot of features people tend to expect: stepping through code, in particular, is painful unless you recompile with DEBUG 3
- xkriva11 3y agoThere are even languages that can do more crazy things than CL or Smalltalk. For example, in Sinclair BASIC, if you put a breakpoint at some position on the line, you can even modify the rest of the line and continue with execution from the breakpoint without the need of restarting anything.
- _19qg 3y agoIf we are using a Lisp interpreter, which executes s-expressions, we can do similar things, here an example using LispWorks, which has both a compiler and a source-level Lisp interpreter. The function FOO has a BREAK. CL-USER 76 > (defun foo (a) (+ (break) (sin a))) FOO CL-USER 77 > (foo 10) Break. 1 (continue) Return from break. 2 (abort) Return to top loop level 0. Type :b for backtrace or :c <option number> to proceed. Type :bug-form "<subject>" for a bug report template or :? for other options. We are in the break lets get a quick backtrace and move to the right stack frame: CL-USER 78 : 1 > :bq INVOKE-DEBUGGER <- BREAK <- FOO <- EVAL <- CAPI::CAPI-TOP-LEVEL-FUNCTION <- CAPI::INTERACTIVE-PANE-TOP-LOOP <- MP::PROCESS-SG-FUNCTION CL-USER 79 : 1 > :n Call to INVOKE-DEBUGGER CL-USER 80 : 1 > :n Call to BREAK CL-USER 81 : 1 > :n Interpreted call to FOO What is the current source? CL-USER 82 : 1 > :lambda (LAMBDA (A) (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 8220104A8B>)) (DECLARE (LAMBDA-NAME FOO)) (+ (BREAK) (SIN A))) Let's change the code: CL-USER 83 : 1 > (setf (third (fifth *)) '(* a 4)) (* A 4) Let's see the new code. CL-USER 84 : 1 > :lambda (LAMBDA (A) (DECLARE (SYSTEM::SOURCE-LEVEL #<EQ Hash Table{0} 8220104A8B>)) (DECLARE (LAMBDA-NAME FOO)) (+ (BREAK) (* A 4))) Move to the BREAK stack frame and return 2 from there: CL-USER 85 : 1 > :p Call to BREAK CL-USER 86 : 1 > :ret 2 42 As you can see, we have changed the running source code, without the need to restart anything.