[HN Gopher] Hotcaml: An OCaml interpreter with watching and relo... ___________________________________________________________________ Hotcaml: An OCaml interpreter with watching and reloading Author : todsacerdoti Score : 45 points Date : 2022-01-19 19:45 UTC (3 hours ago) (HTM) web link (github.com) (TXT) w3m dump (github.com) | dwohnitmok wrote: | The thing I'm always curious with hot-reload systems is whether | there's a good story for state change. What happens if a `ref`'s | type is changed? Are `ref` values preserved between reloads? | | EDIT: Ah I just read https://github.com/let- | def/hotcaml#synchronous-and-asynchron... so it looks like at | least for the synchronous `hotcaml` bit it just completely | reloads from scratch so state is not preserved, but I'm curious | then how the `hotcaml_lwt` frontend deals with this issue. | def-lkb wrote: | Both the synchronous and asynchronous frontends preserve as | much state as possible (all untouched modules are kept). They | differ in the control flow they permit (the asynchronous one | being more expressive). | | I will try to make a parallel with a simple Makefile-driven | project. | | In the initial build, all files are built, following a | topological ordering of the dependencies. For the Makefile it | means invoking some unix command for each intermediate | artefact. For Hotcaml, it means parsing, typing, compiling and | loading each module. | | After that, build is incremental: when a file is modified, only | this file and its reverse dependencies need to be rebuilt. Make | will keep the existing artifacts that are not out of date. | Hotcaml will keep the existing modules that are not out of | date. And their state is preserved. | | Now, the synchronous frontend is quite like a regular Makefile: | a build step is considered done when the build command | finishes. The asynchronous frontend allows command to run in | the background, like a Makefile that would spawn | processes/daemon using the shell & control operator. | | In Hotcaml, these threads continue executing concurrently with | the reloading process. They can be notified that their "host" | module has been reloaded by registering with some runtime | service (via a module named Hotlink). | munificent wrote: | The Dart VM supports stateful hot reload and it's used heavily | by Flutter developers. There are some kinds of structural | changes that necessitate a full restart that wipes state away, | but the VM is suprisingly good at migrating the existing | objects in the heap to match any changes to the underlying | classes and preserve as much state as possible. | | https://docs.flutter.dev/development/tools/hot-reload | rsstack wrote: | 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 wrote: | Right 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 wrote: | I 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/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. | brightball wrote: | Is this pronounced "hot-ca-mal-e"? If it's not it really needs to | be. | LAC-Tech wrote: | awesome. | | It's been a real PITA to crash out of an interpreter then reload | it again. Dune helps in that it will load the libs for you, but | you've still got to open modules etc. | malkia wrote: | btw, there is an awesome podcast on ocaml - | https://signalsandthreads.com/ ___________________________________________________________________ (page generated 2022-01-19 23:00 UTC)