Hacker News new | past | comments | ask | show | jobs | submit login
Coding in the Debugger (2007) (tidyfirst.substack.com)
75 points by KentBeck on Sept 28, 2023 | hide | past | favorite | 31 comments



This is debugger driven development

In programming environments with very powerful debuggers like .NET this is relatively common since it allows you to do a lot of stuff at fly.

Change values, evaluate expressions, change function's code, jump ahead and behind, etc, etc.

Once you try this you'll never want to go back to print-debugging (except for specific cases)


You can also run arbitrary code at any breakpoint (at least for Java with Eclipse).

Want to check the content of a buffered image? Just run ImageIO.write(...) while the application is stopped. Want to check the current working directory? Paths.get(".").toAbsolutePath()

Heck you can even add code as breakpoint condition (which does not need to stop at the breakpoint), e.g. for some on the fly print debug. Changing values does not have to be a manual process but can also be injected as breakpoint condition.


It is also possible to do most of that with Python in Pycharm (except maybe jump behind?).

This is why going from Python to Go can feel like going backward. IMO, even compiled languages should have an "interpreted mode" for development. Once the development is complete, the code can still be compiled to get the benefits of runtime performance.


It's mostly a matter of engineering, Visual C++ has had the ability to change function bodies and continuing running from the point of a crash (as long as data wasn't badly corrupted) since at least Visual Studio 6 (Yes, back in 1998!!!).


the power of debugging in interpreted languages is so far unbeatable. I have a shortcut for "import pudb; pudb.set_trace" in my IDE (pudb is pdb with UI)


Some compiled languages do offer similar REPL tooling,

Java, Scala, .NET (VB, C#, F#), C++, Haskell (Leksah/GHCi), OCaml


I used to use OzCode in C# around 2014 or so, and from my memory it was better than anything available today for an interpreted language.

Just looked it up again since it's been so long. Looks like DataDog acquired them and are ending the product for an in-house replacement, quite a shame.


VS has hot-reload nowadays anyway, and a REPL.


sometimes though when debugging multithreaded code, tracing/logging is easier to figure out what's going on vs pausing on breakpoints.


Yeah, I've found the Elixir debugger to be pretty useless when debugging multiple processes. I make have use of logging in such cases, and the language abstractions are usually easy enough to understand that I don't really miss a debugger. A huge benefit is that because I'm usually working w/ data structures that don't obfuscate the state within objects/processes, I can look at data the data and just figure out what's going on. The primary reason I want a debugger in Ruby is because some mysterious object from who-knows-where is hiding all the state & I'm just trying to figure out where the heck it came from, let alone what's actually in there.


>(except for specific cases)

Exactly, that's what I meant


I just remembered the Tracepoint feature though (it's been a while since I was working in C++ with visual studio). Even when you can't pause execution to debug it's still better to add your tracing in the debugger rather than having to make code changes.

I was always doing stuff on windows/macOS/iOS/Android client libraries so I was always jealous of linux systems programmers who get to leverage Mozilla's rr tool. That's the coolest debugging tool I've ever seen.


Tracepoints are supported in C++ and .NET, the JVM also has them, although the form depends on which implementation is being used.

Naturally similar stuff also exists in Smalltalk and Common Lisp environments.


Sadly rr cannot work on software that makes any kind of call to GPUs, so its usefulness is pretty limited on a lot of larger software. But when it's usable, imo it's amazing.


Sorry this might sound stupid but does that include software with UIs? I’m thinking of a browser where it can be gpu accelerated or not.


If the UI is not GPU accelerated while you are recording, rr will work fine. You can even have GPU calls in the code while recording, they just can't be on code paths that are taken. So a simple command line flag that makes the code choose to use CPU rendering instead of GPU rendering should be fine.

That said, GPU rendering is one of the things that deterministic replay could be most useful for, so it's unfortunate that this doesn't work in rr for now.


Which is also supported in IDE debuggers.


For my job I work in Pharo. So I am still doing this all the time, haha.

What’s also really neat is to be able to work “inspector-driven”. By that I mean to inspect an object and send messages to it directly in order to understand how to interact with it. This becomes even more true if you need some temporary global data that has no permanent reference to hang around for a bit longer.

Question: I want to make a tutorial about creating a Selenium scraper with Pharo along with some data visualization and post it on here. I have noticed that Pharo is really strong on those things. Does anyone have an idea which site I should pick? Perhaps Hacker News itself? Also, the tricks I will be showing there would also be really handy for Selenium web tests. I wonder if people ok HN would be interested in that.


I've seen so much absolutely crap code that I bet would never have been written if the author had just taken the time to step back and think and look at the big picture before writing a single line instead of focusing on microscopic bits and being hand-held through writing it all. After seeing what typical Enterprise Java looks like, I'm not surprised when I read articles about doing things like this.

TDD gives programmers a false sense of correctness. The temptation to "mess around with it until it passes" is far too great.


Its funny, as I am still not good at step debugging in lisp, but https://malisper.me/debugging-lisp-part-1-recompilation/ is a great example of basically the same concept there. Really, that whole series was amazing fun to read through.


In Smalltalk this was always possible! In Java the default JVM implementation is able to do "hot code swapping" only for method bodies. Smalltalk was able to replace everything - even class restructuring. There was a research project at Sun/Oracle [1] to add JVM support for all possible changes in "hot code swapping"... but the implementation was not incorporated into JVM because of increased maintenance complexity so the author made a JVM fork and named it DCEVM and is maintaining it [2]. I thing this project is also connected with HotSwapAgent [3]. There is also a completely different commercial implementation of the hot-swapping capability for Java called JRebel [4] which is used on many software development projects...

[1] https://ssw.jku.at/dcevm/ [2] http://dcevm.github.io [3] http://hotswapagent.org [4] https://www.jrebel.com


When I was young, we programmed in the debugger all the time! And we liked it! https://everything2.com/title/Writing+.com+files+with+DOS+de...


I used to work with some ex-Smalltalkers who did this all the time, while complaining about his much worse Java's debugger was than Smalltalk's.


Here's a quote which I got from comp.lang.lisp, long ago:

Here's an anecdote I heard once about Minsky. He was showing a student how to use ITS to write a program. ITS was an unusual operating system in that the 'shell' was the DDT debugger. You ran programs by loading them into memory and jumping to the entry point. But you can also just start writing assembly code directly into memory from the DDT prompt. Minsky started with the null program. Obviously, it needs an entry point, so he defined a label for that. He then told the debugger to jump to that label. This immediately raised an error of there being no code at the jump target. So he wrote a few lines of code and restarted the jump instruction. This time it succeeded and the first few instructions were executed. When the debugger again halted, he looked at the register contents and wrote a few more lines. Again proceeding from where he left off he watched the program run the few more instructions. He developed the entire program by 'debugging' the null program.


I love doing this in Python/Pycharm. I feel like there are three development modes:

1. Greenfield new development, on unknown parameters (complicated APIs, data frames). I like to use Jupyter Notebooks for that. I use them like a really powerful repl, nothing lives permanently in a Notebook.

2. Type Driven Domain Driven development. Either as a result of building a running MVP through 1, or on a domain you control / understand well. You start from frist principles and model out the flow in Types (usually DataClasses in Python).

3. Debugger driven "Adding Features/ Debugging". Obviously, we use the Debugger to debug, but it can also be very powerful to add a feature to a large system.


I still do this all the time with Java. Especially because the application is rather slow to start or setup whatever I want to debug. It can also influence how you structure the code. In my opinion to the better.

If you mutate state all over a method it is harder to "restart" the method after changing it. Instead I tend to either not mutate state and return the result or work with local variables and just change the object at the very end of the method.

Or might start to more separate a lock/transaction from what is processed within because when "restarting" the method you don't want to relock it.


I'm a big fan of repl driven development for some tasks but you do need to go back and refactor plus add tests.


I often write some code, and then edit and correct it as I step through it, since I know there is a 99% chance that there will be bugs in it


And this, boys and girls, is why you want to use a real IDE with an integrated debugger.


So emacs, right??


I'm actually a big fan of gud-mode and dap-mode in Emacs. They don't have as many features as some other debugger UIs, but the integration with the editor itself is unmatched imo.




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

Search: