4 ms·
Check out how Erlang/Elixir/BEAM deal with this. Stateful processes write a state-migration function that's run (new code, old state) when hot reloading the pro
by rsstack 5y ago
Check out how Erlang/Elixir/BEAM deal with this. Stateful processes write a state-migration function that's run (new code, old state) when hot reloading the process. Requires some forethought, especially when processes can be updated in any order, but it's really amazing. Of course, when doing hot-reloading in a local development environment and not in production, it doesn't make as much sense.
- dwohnitmok 5y agoRight Erlang has explicit migrations and dynamically-typed image-based languages just persist the state. I'm curious if there have been any similar things for statically-typed languages.
- def-lkb 5y agoI am the author of Hotcaml. There is actually some notion of persisting state in it. Reloading is done at the granularity of a module. The reverse dependencies of a module that changed are also reloaded, but the dependencies are not. The runtime state of all modules that are not reloaded is persisted. Here is an example: https://aws1.discourse-cdn.com/standard11/uploads/ocaml/original/2X/1/16dc309be61d3f54918b76bb077b846d2f61dea8.gif https://aws1.discourse-cdn.com/standard11/uploads/ocaml/orig... The dependency graph is roughly: system layer -> renderer -> slideshow The system layer initializes the window (with SDL) and an OpenGL context. The renderer allocates resources (buffers, fonts, ...). The slideshow only defines the content to be drawn. In the live code, only the slideshow is modified, so the system and renderer states are not affected. Doing reloading at the module granularity meshes well with ML semantics: it is a straightforward extension of the "hyperstatic environment" and it preserves type safety and modular abstraction. A static language that is designed with hot reloading in mind could do better, the generative nature of ML type definitions is not ideal. I guess that structural type systems permit a finer grained notion of reloading. Actually, a finer-grained notion of persistence and state migration could be built as a library (with some macros) on top of Hotcaml. The important step is to be able to reify type definitions and then to define some notion of "type compatibility" (between old and new modules) by induction on the structure of types. This is a lot of work, but could be built on top of Hotcaml foundations.
- dwohnitmok 5y ago> Reloading is done at the granularity of a module. The reverse dependencies of a module that changed are also reloaded, but the dependencies are not. The runtime state of all modules that are not reloaded is persisted. Ah that makes sense to me, and explains to me why in your linked demo the rotation resets after every color change, but the other stuff doesn't. That does mean though that having the circle not reset after every color change is probably not feasible unless the module order is fairly convoluted right? (because most straightforward ways I can think of organizing the code would have the circle motion as a reverse dependency of the color of the circle).
- def-lkb 5y ago> having the circle not reset after every color change is probably not feasible unless the module order is fairly convoluted right? Not necessarily no. The thing is that you could have an early module that implements a framework to manage state. For the circle rotation, it is quite easy, it is a single number. You could do something like: `let circle_rotation = managed_state "circle_rotation" Float 0.0` "The rotation of the circle is represented by a float initialized to 0". Then even when your module is reloaded, the hypothetical framework takes care of preserving this piece of state.