4 ms·
Only being able to change function implementation (and non generics only at that) seems like a substantial limitation. Its not often I’m quickly prototyping som
by dymk 4y ago
Only being able to change function implementation (and non generics only at that) seems like a substantial limitation. Its not often I’m quickly prototyping something that would benefit from hot reloading, and not also changing data layout as I’m iterating.
I’m curious to see if the sharp edges will soften as time goes on. Mangling structs to be pinned to a particular loaded library version somehow, and injecting indirection where they’re used, would take this a long way. But would probably require compiler support.
- robertkrahn01 4y agoYeah the approach is restricted and more compiler support for this kind of workflow would be incredibly welcome. I wrote this in part to try to get more folks in the Rust community thinking in this direction. The hot-reload support that Zig is planning sounds really exciting and I would love for Rust to have something similar (one can dream, right ;). That being said, you can still go quite some way with this approach. On the one hand, simply being able to twiddle an algorithm into shape is really handy when making a game, visualization or exploring data. On the other hand, you can also serialize state or keep it in a generic form like a serde_json::Value. Serialization of course needs some kind of migration on the part of the code using it (if the data layout changes it loads an old version and needs to convert it to the new form) or defaults for newly added fields/types. However, this is true in general, even in other languages.
- dymk 4y agoLike you say, modeling the interface between the shared library like a Thrift struct (which can be serialized) may be beneficial, and would facilitate adding/removing fields by having e.g. default fields. Or just crash if a non-backwards compatible change is made, e.g. a new field is expected but not present, but ignore fields that are present but no longer expected. I think the other killer feature that this is missing is being able to have a "release" compilation mode that removes the hot reloading entirely, and seamlessly statically links in the library.
- robertkrahn01 4y ago> have a "release" compilation mode that removes the hot reloading entirely Oh that is easy to do thanks to Rust features, see the reload-feature example: https://github.com/rksm/hot-lib-reloader-rs/tree/master/examples/reload-feature https://github.com/rksm/hot-lib-reloader-rs/tree/master/exam...
- dymk 4y agoVery cool!
- forrestthewoods 4y agoIs there any language that supports hot reloading + data layout changes? I’m not sure that even makes sense.
- dymk 4y agoErlang, JavaScript, Ruby, Python come to mind. Dynamic languages which inherently don't expect data to have a statically enforced shape. Doing it in a statically typed language would be substantially harder, and to make it feel "good", probably require lots of tracking of library versions associated with particular data objects or strict isolation of how data passes across the library boundary. I don't think there's a great solution to be had.
- steveklabnik 4y agoThose all don’t let you change your data’s layout: they’re always behind a pointer, no? It’s a uniform representation.
- robertkrahn01 4y agoIn JS for example, if you change the prototype of an object you have effectively changed it's data layout but of course everything is behind a pointer / an indirection. When changing instance or class variables in Smalltalk, the system actually changing the object layout and goes and recompiles code using it. If you are interested in the details: Chapter 5 of [1] explains it a bit. [1] Hirschfeld et al. Assisting System Evolution: A Smalltalk Retrospective. http://soft.vub.ac.be/Publications/2002/vub-prog-tr-02-25.pdf http://soft.vub.ac.be/Publications/2002/vub-prog-tr-02-25.pd...
- steveklabnik 4y agoThanks!
- dymk 4y agoYes, the indirection (and also late binding) is why hot reloading is (somewhat) ergonomic in those languages, but would be difficult to do in Rust (or C++, etc). I think the shared library types would need to be indirected either via compiler support, or some kind of `Hot<T>` wrapper that acts like a `Box<T>` when hot reloading is enabled, and like a `T` in "production" mode to be ergonomic.