4 ms·
Debugging Lisp (2015)
- aidenn0 6y agoI now have a good place to link to when talking about lisp debugging being the killer feature that keeps me coming back to lisp as a language. I usually get very confused responses when I say this, as people think "single step through the code" when I say "debugger" and I respond with something like "I'm pretty sure there's a way to step through the code in SLIME, but I never learned it because I've never had a need for that." A quick skim through the series shows that the author feels the same way; there doesn't seem to be a mention of SLDB's stepper.
- fiddlerwoaroof 6y agoIt's implementation dependent, but something like this works with sbcl: C-u C-c C-k ;; recompile with (debug 3) (step (some-function)) I also never do this
- deleted 6y ago[deleted]
- lokedhs 6y agoI discovered the "s" key more or less by accident. Since I learned that you actually can single-step, I've used it a few times, but most of the time it's not necessary. Compare this to another project I've been working on which is written in Kotlin. Almost every debugging session involves a lot of single-stepping. There is no insightful point of this reply, except for agreeing that Lisp is powerful enough that single-stepping is mostly pointless. I do add a lot of (break) statements during debugging though.
- bcrosby95 6y agoRealistically, how often do you need to redefine a class and care about having to restart your runtime?
- EdwardCoffin 6y agoI have done this to debug a difficult to reproduce bug, where restarting the runtime would have lost my hold on the occurrence.
- lisper 6y agoIt can be incredibly handy if you are doing a computation with a lot of state. I'm currently working on a tool that does chip design, the state for which runs into hundreds of gigabytes. Being able to redefine a class without restarting can be an absolute life saver in a situation like that.
- patrec 6y agoExactly. For exploratory programming with long running computations losing all your state because of something you could fix by hot-reloading a one line change can be rather frustrating -- I remember cursing at python years ago when I was running some ML experiments and more than once lost all data right at the end due to some silly bug at the serialization stage that would have been one line to fix. Mind you, with python you can at least run things with ipython --pdb to get thrown into a debugger on failure so you can potentially serialize some state before losing it. And stacktraces are better than common lisp's. But having a robust way to redefine stuff or fixing up a failed computation is definitely very handy in some contexts.
- p_l 6y agoCan you give an example of Python stacktrace being better than CLs? It hasn't been true in my experience, so I'm wondering.
- patrec 6y agoA good example would take a fair amount of space, but let's try this bogus example: This is ipython: In [2]: os.path.join(None) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-2-ba05fdaae739> in <module> ----> 1 os.path.join(None) /opt/anaconda3/lib/python3.8/posixpath.py in join(a, *p) 74 will be discarded. An empty last part will result in a path that 75 ends with a separator.""" ---> 76 a = os.fspath(a) 77 sep = _get_sep(a) 78 path = a TypeError: expected str, bytes or os.PathLike object, not NoneType This is SBCL: * (merge-pathnames nil) debugger invoked on a TYPE-ERROR in thread #<THREAD "main thread" RUNNING {1000560083}>: The value NIL is not of type (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING PATHNAME SYNONYM-STREAM FILE-STREAM) when binding PATHNAME Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (MERGE-PATHNAMES NIL 70256781343884 MERGE-PATHNAMES) [external] 0] I find the first much quicker to read and parse (better layout, no SHOUTING, color coded, context info) and you can immediately see what file and location you'd need to "fix". What is an example were you prefer the lisp stacktrace to something you'd get in interactive development with ipython or in production with newrelic or anything else that captures python stacktraces?
- deleted 6y ago[deleted]
- phoe-krk 6y agoWarning: a bit of a shameless plug. I have recently given an interview[0] for Immutable Conversations where I show some of the techniques described in these blogposts. In the video, inspect the state of the Lisp image, and I evaluate arbitrary code (redefining functions and variables) while not leaving the debugger. Perhaps HN can find this interesting, as it is a livecoding demonstration of how a Lisp programmer might make use of these techniques in real-life scenarios. The examples are trivial and might be perhaps a bit too trivial for people used to programming, but the secondary point of the video was to demonstrate the livecoding techniques to people who possibly do not know Lisp whatsoever, and I didn't want to burden them with complicated code examples. (The primary point was to describe the Common Lisp condition system, which I have written a book[1] about, and show the basics of control flow in Common Lisp that are the foundation of conditions.) [0] https://www.youtube.com/watch?v=pkqQq2Hwt5o https://www.youtube.com/watch?v=pkqQq2Hwt5o [1] https://news.ycombinator.com/item?id=24867548 https://news.ycombinator.com/item?id=24867548