[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)