[HN Gopher] Debugging Lisp: fix and resume a program from any po... ___________________________________________________________________ Debugging Lisp: fix and resume a program from any point in stack Author : todsacerdoti Score : 58 points Date : 2022-12-06 14:54 UTC (8 hours ago) (HTM) web link (lisp-journey.gitlab.io) (TXT) w3m dump (lisp-journey.gitlab.io) | vindarel wrote: | Hi everyone, happy to share more about my Common Lisp journey if | you have any question. | TacticalCoder wrote: | People using Emacs without _paredit_ or _lispy_ to automatically | close parentheses / do semi-structural editing _should be put in | jail!_ ; ) | Labo333 wrote: | I'm wondering whether it would be possible to build some debugger | for Python to fix that! | | For example, I modified my IPython config to always activate | https://ipython.org/ipython-doc/3/config/extensions/autorelo... | | It works well for modules with redefined functions. So if you do | from module import f1, f2 ans1 = f1() | ans2 = f2(ans1) | | and f2 fails, then you can just modify the code of module and | relaunch `ans2 = f2(ans1)`. | | What is not available is reloading classes, for example if it | looks like: from module import Class | c = Class() c.f1() c.f2() | | and there is a bug in f2, then the class won't be redefined. | | I guess there is no perfect way to do it (for example what if f2 | needs some variables defined in Class.__init__), but the | situation is the same for Lisp with its dynamic typing. | | So maybe the situation would be to have some command like | `%reload Class`. | | The other obstacle is restarting from a frame, and I understand | that Python's standard exception handling doesn't allow that. But | pdb exists so there should be a solution. | sidmitra wrote: | Some of the basic hot-loading features can probably be | approximated in Python. Here's some from my bookmarks(i've not | tried them personally) | | - https://github.com/breuleux/jurigged | | - https://github.com/reloadware/reloadium | | I would imagine lisp can do this on a whole different level. | Emacs seems like a testament to that. Basically the entire | editor feels like eval() | gjvc wrote: | jurigged is excellent. | gumby wrote: | Lisp has a lot of capabilities here that Python doesn't. It has | restartable exceptions, the ability to redefine functions and | whole classes at runtime, the ability to write new functions | (/variables/classes etc) in the process of those redefinitions. | Its debuggers are written in Lisp (completely extensible by you | at runtime) offering a REPL right at the debug site. | | Python is a completely different beast. | Jtsummers wrote: | > the situation is the same for Lisp with its dynamic typing | | Common Lisp and Smalltalk (quintessential dynamic systems) both | track the existing instances of a class. If you update the | class definition then they can update the existing instances of | the class. In CL you'd want to specialize `update-instance-for- | redefined-class` to handle the update. | | http://clhs.lisp.se/Body/f_upda_1.htm#update-instance-for-re... | thelopa wrote: | Most CL implementations don't "track" the instances so much | as have them point at a proxy for the real class object. When | redefining a class, the old proxy object is marked as stale | and then updated to point at the new class. This allows the | runtime to lazily update instances to the new class (using | the method you linked to) as they are encountered. As a | result, you can have instances from several different class | generations kicking around in memory. | mrweasel wrote: | I suppose you could create a new class, with any fixes and wrap | the existing object in the new class. It will kinda work, due | to the duck typing, but it's not that elegant. | | For the restarting, yeah, I don't know either. | henrydark wrote: | in ipython just running %debug will get you in pdb in the | particular frame that threw, there you can modify stuff using | normal python, and then you can tell pdb to continue | jorams wrote: | > I guess there is no perfect way to do it (for example what if | f2 needs some variables defined in Class.__init__), but the | situation is the same for Lisp with its dynamic typing. | | CL has the generic function update-instance-for-redefined- | class[1] for this, so you can customize what happens to | instances when a class gets redefined. I think most developers | don't actually define methods for it all that often, but it's | there if the defaults don't work for you. | | [1]: | http://www.lispworks.com/documentation/HyperSpec/Body/f_upda... | stonemetal12 wrote: | PDB has the interact command that drops you into a full blown | python repl at the debug point. Changing an existing method on | a class isn't a big deal. Redefining a class is possible as | well but updating existing instances to the new class requires | metaprogramming tomfoolery. | artemonster wrote: | IMHO, if CL got their handler system a tad tiny step further and | better, they would have landed in a full algebraic effect | territory, with a total flexibility of resuming your ,,throwers" | and not only restarting them. Paired with unparalleled CLOS | capabilities that still drives context oriented programming, | aspects, subjective dispatch research, CL would have been a | religion by now. | fiddlerwoaroof wrote: | I don't quite understand what you mean by the distinction | between resume and restart here. CL condition handlers allow | code that signals a condition (sort of equivalent to "throws an | exception) to continue on as if the condition was never | signaled. You just need a handler-bind somewhere in the stack | that doesn't perform an exit. You can use this to do things | like catch a type error and convert the input value to the | expected type on the fly. | moonchild wrote: | You can do the same thing in j, using the 'cut back' debugger | command. It is a useful and powerful facility indeed. ___________________________________________________________________ (page generated 2022-12-06 23:01 UTC)