Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

fyi, "hot reload" is a native part of every operating system (consider, even trivially, forking or https://en.wikipedia.org/wiki/Dynamic_loading).

It's a sign of how bad developer tooling has been that live reload is sold as an add-on feature. DX seems always to see-saw between bill gate's c. 1990 demo of VB, and the compile-time speeds of a N' Wirth.

At a guess, when the internet happened, all DX had to be thrown away and we still arent back to where we were 30+ y ago.

I support being paid for your work, but live reload is a fairly trivial thing to write for yourself -- I spent one day this gone weekend writing a debugger in C which does it.

(consider also, https://github.com/tsoding/musializer which has live rebuild via the nobuild system in nob.c)




One problem is that modern software architectures are highly coupled and stateful, such that it isn't possible to hot reload a component. It would require the host (e.g. when using a DLL) to detect a change, save state, unload, reload, load state. Multi-threading may also make things more difficult, requiring more synchronization during changes.

I agree with your sentiment, but it's really hard to communicate it to the younger generations. I suppose it comes off as being negative, but it's really just melancholia over the loss of something that was fun, simple, and powerful.


well, i think the issue is as least as much that the developers who create these architectures do not start from this pov ---

consider how these architectures would be designed if must-have condition was sub-100ms iteration -- which should be trivial all-but-for codebases of at least 1mil+ lines; them, well, maybe it's 200ms.

This design isnt hard -- what's hard about save_frame(), save_state(), or w/e, and restore_state()?

Only that it would need to be actively maintained and developed -- that is, it would obligate developers to tend to their own ability to work.

What i think here is lost is not, somehow a simple system which can be magic, but the concern of developers to maintain such systems.

Why? Certainly, many reasons. But my comment here today is more to frame the issue: this 'feature' can, and should, be part of ordinary development. It isnt that hard.

Even if save_frame() is no longer a register copy, but somehow, an obscene json serialisation process.


Way back in the 2000-2004 timeframe, I worked along side a team making a game for the OG Xbox that had a daily workflow like:

1. Come in, get coffee, check out latest code from Visual SourceSafe. 2. Hit F5 to start debugging. 3. Edit and Continue in Visual Studio 6.0 all day long. 4. Hit shift-F5 to stop debugging at the end of the day. 5. Go home.

Between that and the OG Pix for Xbox, the development experience has been all downhill from there. A lot of kids these days tried GDB once or twice and then grew up without even understanding the value of debuggers at all. And, by "kids" I mean "graduated 10 or less years ago" :P

I'm sure keeping that workflow working was a fair bit of work. But, it was worth it!


X360 dev was the same, I lived inside the VS debugger and perpetually had Pix up in a second monitor.


I'm working on a UE5 game right now using Live++. My day is now check out from perforce, hit F5, Ctrl+alt+F11 to hot reload, and for 98% of what I want to do, it works perfectly.


MS-DOS, Windows, .NET and Java development for me, during the last 30 years.

One of my university assignments, in the mid-1990's, was to implement a B-Tree library in C, which I used a OOP based approach, and already back then, gdb was powerful enough to use as a poor man's REPL.

I really don't get why people shy away to learn to use their tools properly.


Yes, but:

Components depend on other components, and they all have to support hot reloading. And what about side effects? For example, an open network connection, or a window. You could store the state (handles etc.), but what about callbacks during the reloading phase? They'd have to block and wait.

Ultimately, what you need is a message passing architecture that supports all this. Smalltalk. Alan Kay has been a vocal critic of our modern architecture. See his talk "Alan Kay at OOPSLA 1997 - The computer revolution hasnt happened yet".

But that architecture is computationally inefficient.

I suspect the problem is that computers weren't fast enough for the last 30 years. So we focused on performant computing. We still do that, with high fps gaming. And adding better quality graphics. Soon we'll have Apple Vision Pro with a 4k display for each eye.

My personal hope is that WebAssembly and the Component Model will drastically change things, by introducing API virtualization and effectively decoupled modules, but this will require that tree-shaking/deadcode removal is disabled.


Something like COM, XPC or Binder, no need for WebAssembly "re-inventing" it.


I feel like to some extent the problem here is the dynamic linking model that is almost universally used. If programs were designed from the perspective of the linker, then the linker could maintain a graph of function dependencies and have a cascading invalidation upon update. It is hard to retrofit this onto a project that is already a standard make based project.


Look, I'm part of the new generation. I think live plus plus is awesome, but don't really want to pay for it.

If what yout talking about is "not that hard" can you show me how to do it?

If it's not that hard, why aren't you teaching anyone? Why isn't it ubiquitous?

Your comments seem so at odds with reality that I'm inclined to think your missing something. But I'm also intrigued. Is it not that hard? And if it's not hard, why is live plus plus successful?


I was also suspicious but I think this system does have advantages over the OS interfaces for this: incremental compilation and binary patching. If this goes down to the function or block level definitions and is fast that's pretty sweet. The only time I've enjoyed that kind of DX is with Common Lisp/CLOS.

Update: there's a "deep dive" power-point that goes into a bit more detail: https://liveplusplus.tech/downloads/THQ_Nordic_Dev_Summit_20...


fork() doesn't hot reload much of anything.

exec() doesn't hot reload either.

Dynamic loading doesn't hot reload either, more like hot load.

Debuggers might hot-patch code to insert breakpoints, but that's not the same thing as replacing running code. Sure, the debugger might execute scripts you associate with breakpoints, but that's also not exactly the same thing as replacing the running code. Mind you, debuggers do have to make sure that such hot-patching is atomic, or they have to stop all threads.

Hot reloading has a ton of considerations:

- threading -- you need to quiesce all threads at points where they are not executing the code to be reloaded _or_ you need to load the new code and hot-patch either calls to old code and/or old code function entrypoints to jump to the new code, but if the latter then you need to make sure it's ok to have a mix of threads executing old code while the new code comes online

- data structure compatibility -- if structures have changed you may not be able to hot-reload, but you need to at least be able to detect incompatible changes, and at best you need to plan how the hot-reloaded code will upgrade extant data structures on the fly

- and more

Sure, if you atomically hot-patch all the calls to old code or old code entry points, then threading issues on the side of the hot-reloading library go away, but you still have to think about how old and new code running concurrently will deal with each other.

Now, I don't know that much about this subject, and I've seen how old Lisp and Smalltalk systems could hot-patch/reload all the live long day with no problems, but I suspect all the systems where it was ever easy were a) single-threaded, b) written in high-level languages, c) still had some reloading considerations for the authors of the code being reloaded.


> Debuggers might hot-patch code to insert breakpoints, but that's not the same thing as replacing running code.

Solaris dbx did have this capability -- patch and replace code with newly compiled code from your updated source files -- circa 2000. You just typed "fix" and it worked. I've been wishing for that capability on x86 Linux ever since.


Nice! I never knew, and used dbx lots!


God, it was so, so convenient. Near instant turnaround time for fixes. It was especially good in combination with 'pop', which returned control to the calling function just before calling the current one. It gave you a sort of limited form of do-over, with the caveat that it didn't try to undo any effects of the called function so far. Or you could just fix and restart.


> ... a) single-threaded

Well, one counter-example: Erlang.

But Erlang is typically the exception to any rule.


Shared-nothing threading is definitely easier to deal with in hot-reloading, and I should have thought to mention that.


> exec() doesn't hot reload either.

If you store all your data in mapped files, you can remap them after execve and continue where you started from. This works if the data layout hasn't changed. If you have per type memory maps, you can explicitly convert only the data that has changed. You might need redo logs for things that can't be persisted (networking for example).

Not easy, but also not impossible. All your other concerns still apply of course.


Besides therealcamino answer, Energize C++ and Visual Age for C++ v4 provided a image like development experience for C++, including code replacement and incremental compilation at method/function level.

Sadly too expensive for their day, and eventually died, only for us to start having some of those features almost 30 years later.


> fyi, "hot reload" is a native part of every operating system (consider, even trivially, forking & reforking).

Can you expand on this?



This doesn’t answer the question, and doesn’t really help with hot reloading at all outside of the most basic examples.


>I support being paid for your work, but live reload is a fairly trivial thing to write for yourself -- I spent one day this gone weekend writing a debugger in C which does it.

Major Dropbox “who would pay for this over just using rsync?” vibes here. Never change, HN.


unlike the dropbox case, my point isnt, "oh go and do it yourself" -- my point is why-t-f doesnt gcc/clang, etc have a obv-build-tool --live-rebuild option?

Or, more alarmingly, why are things like jrebel fawned over? Rather than, say, it being an embarrassment that java dx is worse than programming dx 30-40 years ago?

Why isn't the basic thing all OS do, ie., live reloading of code, a day-to-day essential element of all development?

I really don't know. But to be clear, it was 50+ yr ago, 40+ yr ago, 30+ yr ago --- and as of today, it's $100/yr subscription (lol?!)




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: