| > Semantic introspection, unfortunately, turned out to introduce large compile-time costs which made it difficult to keep stateful hot reload hot. They must have done something wrong. Macros are expanded when you ahead-of-time compile your code, which doesn't take place in the run-time environment where you hot load, but in the build environment. It doesn't matter whether the macro are simple, or whether they can inspect lexical environments and look up type info and whatnot. Compile-time costs should never factor into hot reload, because the stuff being loaded should already be compiled. Maybe they aren't explaining it; there could be certain semantic problems preventing existing state from being re-used on what should be a hot reload. Macros create certain issues in reloading. If you change a macro such that the expansion requires different run-time support which is incompatible with existing expansions, you have problems. One option may be to reload all the code which depends on those macros, so that everything cuts over to the new run-time support. If you need to support a mixture: hot-reloaded modules using the new versions of the macros, side by side with code made using the old versions, then the old version of the run-time support has to coexist with the old. If the run-time support for the macros is something which manages state that needs to be preserved on reloads, then that can cause difficulties. The old and new macro expansions want to appear to be sharing the same state, not different silos. |
The user experience with hot reload is:
1. They hit "run".
2. The compiler compiles the app.
3. The app starts running on their device.
4. They change some code in their IDE.
5. They click "hot reload".
6. The compiler compiles the changed code.
7. The IDE sends the updated code to the running app.
8. The runtime loads the changed code.
9. They see the changed behavior in their running app.
Steps 6-8 determine the total time between "user requests a hot reload" and "user sees their updated app". Compilation doesn't happen on the device, but it still takes time and is in the critical path for that experience.
Making the compiler slower makes hot reload slower. We measure hot reload time in milliseconds, so it doesn't take much for us to consider it an unacceptable performance regression.