[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)