Hacker News new | past | comments | ask | show | jobs | submit login

I do quite like common lisp, but:

> In Common Lisp you can certainly choose to panic on or ignore errors, but there’s a better way to work. When an error is signaled in Common Lisp, it doesn’t unwind the stack. The Lisp process will pause execution at that point and open a window in your editor showing you the stack trace. Your warrior’s sword is hovering over the monster, waiting for you. At this point you can communicate with the running process at the REPL to see what’s going on. You can examine variables in the stack, or even run any arbitrary code you want.

This doesn't seem like something that's particularly difficult to do with c/gdb.




> This doesn't seem like something that's particularly difficult to do with c/gdb.

Well, why don't you do it, then? Not trying to be snarky(not much anyway), but I feel you are seriously under-estimating the work involved. Either that, or the description does not make it clear enough.

It's a full blown REPL. We are not talking about just printing out the code at that point, or maybe mutating a variable on the stack. We can execute arbitrary code and even replace entire sections of code with new code, and then hit continue and it works as if nothing happened, only now running the new (and hopefully corrected) code. Just the memory management implications of doing this in C would be very interesting.

Note that you can also do this over a network connection. NASA folks used this to great effect to patch Deep Space-1. Lisp machines also used this capability over the entire OS. I have also used a similar mechanism (with Chicken Scheme) to do incremental development on iOS, without having to do the whole xcode deploy/run cycle.

The closest analog I can think of today is a browser's "console", which lets you do similar things for javascript code.


The closet analog is Smalltalk.

Java and .NET allow for partial edit-and-continue, but they aren't as powerful as Lisp/Smalltalk.


You can put your code in shared objects and then reload them. Well, I've never done it myself as I haven't seen the need but it seems easy enough, you'd simply have to define a macro for defining functions (you'd just have to write them as FUN(void, bla)(int x, int y) instead of void bla(int x, int y)), which would add the function to a symbol table so then you can say reload("bla") from within gdb and then keep running. I'm not quite sure what you mean by 'the memory management implications of doing this in C would be very interesting'? The only thing, really, that you'd expect to stop working static variables.


You might be interested to read more about this not particularly difficult problem, known in general as "dynamic software updating". You can get a general overview on Wikipedia, but I'd recommend having a browse through the work of Michael Hicks and colleagues: https://www.cs.umd.edu/~mwh/papers/mwh-cat.html

They've worked on a number of iterations on this idea, of which these are probably the most interesting and relevant to C:

Original DSU paper (2001): https://www.cs.umd.edu/~mwh/papers/HicksMN01a.html

Proteus (2005/2007): https://www.cs.umd.edu/~mwh/papers/StoyleHBSN06.html

Ginseng (2006): https://www.cs.umd.edu/~mwh/papers/neamtiu06dsu.html

Kitsune (2012): https://www.cs.umd.edu/~mwh/papers/hayden12kitsune.html

I'd caution you that "I've never done it, but it seems easy" is the first symptom of early stage Dunning-Kruger. Don't ignore the warning signs!


There are a few ways in which the shared objects method you suggest does not match the full power of Lisp debugging.

First of all, when a C program crashes, it just crashes. There is no REPL. There is only a core dump. So any live-debugging you plan to do is after the fact. After you have seen a crash, you would now begin to prepare for the next crash by launching your process via GDB or restarting your process and attaching a GDB to it. Whether a similar crash would occur again or not or when it would occur again depends on the nature of the bug. Now contrast this with Lisp debugging when your program crashes, it stops there and offers you an REPL to interact with the program right then. There is no need to wait for the next crash.

Secondly, when you debug with GDB, you would be dealing with syntaxes: The syntax of C that we are so familiar with. The GDB syntax to investigate the problem that we may be less familiar with. When the Lisp debugger offers the REPL to you, you are working with Lisp again. Your compiler, debugger, program, etc. all are part of the same unified environment where you just execute Lisp code to debug your issue.

Finally, putting your code in shared objects and reloading them requires you to go through the complete write-build-test-debug cycle. And then what do you do if your shared object itself crashes? With Lisp you skip the write-build-test part when all you want to do is debug an error. You jump straight to the debug part of the cycle and begin investigating the runtime state. And it works the same in a uniform manner whether your main program crashes or a dependency crashes.


A while back, I remember running samba with the configuration option "panic action = /usr/bin/X11/xterm -display :0 -e gdb ...". On a segfault, you'd get a happy little xterm ready to go. Never managed to recover an operation from that window, though.

I have caught a condition in StumpWM (a window manager written in Common Lisp) and done something useful with it. A completely different beast. Practical Common Lisp has a solid example that may be a bit enlightening (http://www.gigamonkeys.com/book/beyond-exception-handling-co...).


I think this might give a more in-depth introduction to CL’s conditions/restarts: http://www.gigamonkeys.com/book/beyond-exception-handling-co...


And for more on the history and philosophy behind it: http://www.nhplace.com/kent/Papers/Condition-Handling-2001.h...


Live editing the running code without a restart may be a mite harder in C.


It's very hard (corner cases are nasty). That said, there are IDEs out there that support that sort of thing, e.g. https://docs.microsoft.com/en-us/visualstudio/debugger/edit-...


> https://docs.microsoft.com/en-us/visualstudio/debugger/suppo...

Looks like it has some severe limitations when it comes to interactive object-oriented programming:

> Changes to a data type that affect the layout of an object, such as data members of a class.

The Common Lisp Object System does not have such a limitation. The price to pay is some indirection. You don't even need to create new instances from your class. The existing instances will be updated for runtime changes: different inheritance, new slot, removed slot, different class, ...


I have implemented live coding via DLLs for C , it’s not hard to do and can easily replace gdb. I don’t think that gdb offers live coding outside the box. Inspecting live state and to an extend REPL abilities do exist in GDB.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: