> I wish more back-end languages had this experience.
I know what that feels like. I have that same feeling about a whole bunch of languages that has been available in .NET for at least 15 years now.
When I got into programming, I moved from VB6 to VB.NET to C#, the latter two using a cracked version of MS Visual Studio I downloaded at school. I only started seriously using the debugger somewhere around the time I taught myself C#.
Because of this, I got used to the idea that in a normal debugger, you could just click and drag back the point of execution, modify the code, and hit resume. The VS time traveling debugger will actually revert variable assignments, recompile the modified code, insert it in its place, and continue execution. This wouldn't work with P/Invoke calls, but it worked great for what I was trying to do. Debugging and fixing mistakes was absolutely trivial.
Imagine my betrayal when I found out that there was nothing like this in C++, or Java, or Javascript. Java has gotten a similar feature, but I've never worked with an IDE that integrated it even close to how well VS 2008 integrated it.
Even today, this seemingly basic feature that I took for granted just isn't available in many modern IDEs. I understand natively compiled languages like C/C++/Rust/Go not supporting the inline code replacement feature, but the hot reload in languages like Kotlin, Java, and Javascript just don't work like it did for me back in 2008.
As for all these tricks: I think most of them are available in most IDEs. Anything involving conditional breakpoints will work regardless of the language you use (although languages like Rust can have some restrictions). Tracing callers should work in any decent debugger. Timing individual functions may require writing out long package names to get to the right methods, but they should be available. The monitor() trick can be replaced by a logging method breakpoint.
How well DOM-related debugging works, will depend on whether or not your GUI framework uses a DOM and how it's constructed. If you're composing a DOM from multiple individual functions (like in React/Flutter/Kotlin Compose) then you can add breakpoints to all the relevant state alterations. If your tooling uses a more C-inspired windowing mechanism, you're probably going to have to get creative.
When you get down into the weeds of it, I think you'll find that more of these features are available for backend languages than you might expect. I would recommend any developer to occasionally read the changelogs of their IDEs (or to grab an IDE if you normally don't use any) and take a few moments to explore the possibilities of modern debuggers.
I love your description of undoing code execution, modifying the code and continuing. I think too often these days because of the UNIX philosophy of doing one thing well, the debugger and the compiler and even the linker are different projects, making it unnecessarily complicated to combine these tools other than passing blobs of output into another tool's input. We should aim higher.
Back then, Eclipse was what every guide and book told me to use, so that was where I started. These days I'm mostly on Jetbrains products. Microsoft made VS a weirdly slow, bloated piece of kit, but I still miss some of the features they have had for ages.
I don't get automatically reloaded classes in IntelliJ, though I think there's a button to manually reload code manually? The whole ease of development came from not having to manually pick what code to reload while debugging. Java also seems to have a bunch of limitations that C# doesn't have (and didn't have back when I tried it on Windows). For example, you can't add a method, or alter the return type of a method.
As for time travel debugging, I'm not sure how you do that in IntelliJ? I can't even see any way to undo the previous line of execution, let alone step through code in two directions. It looks like there are plugins for a bunch of languages, though, but those are all external tools built by third parties.
Rolling back executed code seems to work in Rider, but I don't seem to get any Edit and Continue functionality on Linux, which is probably a Microsoft thing.
This looks rather neat, and there seems to be ample IDE support as well! It looks absolutely perfect, but makes me wonder why this isn't included in VS Code and IntelliJ by default when you install a (supported) language's debugger.
I know what that feels like. I have that same feeling about a whole bunch of languages that has been available in .NET for at least 15 years now.
When I got into programming, I moved from VB6 to VB.NET to C#, the latter two using a cracked version of MS Visual Studio I downloaded at school. I only started seriously using the debugger somewhere around the time I taught myself C#.
Because of this, I got used to the idea that in a normal debugger, you could just click and drag back the point of execution, modify the code, and hit resume. The VS time traveling debugger will actually revert variable assignments, recompile the modified code, insert it in its place, and continue execution. This wouldn't work with P/Invoke calls, but it worked great for what I was trying to do. Debugging and fixing mistakes was absolutely trivial.
Imagine my betrayal when I found out that there was nothing like this in C++, or Java, or Javascript. Java has gotten a similar feature, but I've never worked with an IDE that integrated it even close to how well VS 2008 integrated it.
Even today, this seemingly basic feature that I took for granted just isn't available in many modern IDEs. I understand natively compiled languages like C/C++/Rust/Go not supporting the inline code replacement feature, but the hot reload in languages like Kotlin, Java, and Javascript just don't work like it did for me back in 2008.
As for all these tricks: I think most of them are available in most IDEs. Anything involving conditional breakpoints will work regardless of the language you use (although languages like Rust can have some restrictions). Tracing callers should work in any decent debugger. Timing individual functions may require writing out long package names to get to the right methods, but they should be available. The monitor() trick can be replaced by a logging method breakpoint.
How well DOM-related debugging works, will depend on whether or not your GUI framework uses a DOM and how it's constructed. If you're composing a DOM from multiple individual functions (like in React/Flutter/Kotlin Compose) then you can add breakpoints to all the relevant state alterations. If your tooling uses a more C-inspired windowing mechanism, you're probably going to have to get creative.
When you get down into the weeds of it, I think you'll find that more of these features are available for backend languages than you might expect. I would recommend any developer to occasionally read the changelogs of their IDEs (or to grab an IDE if you normally don't use any) and take a few moments to explore the possibilities of modern debuggers.