'malleable' Rust apps

https://news.ycombinator.com/item?id=22857551 has an interesting discussion on 'malleable' software, where one example is defined as Emacs Lisp

Question: can anyone share practical experience building 'malleable' software in Rust ?

In theory, there is Gluon / Dyon / Lua / list-likes

In practice, I've never gotten anything to work as nicely as emacs elisp (and do most of my development in IntelliJ/Rust, with the Rust app halted, rather than developing inside the running Rust app).

I have a feeling this would be hard to implement in Rust without creating a massive framework around it. The language relies a lot on static analysis, and I feel like the sort of runtime flexibility discussed by that Malleable Systems article would be hard to implement without garbage collection, some form of reflection, and a way to evaluate arbitrary code at runtime.

1 Like

You could do it so that you've got one universal state structure, and two crates:

  • The first crate manages things that won't change.
  • The second crate can change, and will be reloaded when possible.
    Then, you take the first crate, and compile it, run it and then load in a compiled version of your second crate. Your second crate is what you develop on.

I've done something similar with hot reloading shaders when developing them. It works well, even when doing it on Android.

By load the new crate in, I mean as a dynamic library, so you can use libloading to reload it, or the dylib loader of your choice. It would probably be difficult to make it easy to switch between debug and release though.

1 Like

Item 6 is, "Modifying a system should happen in the context of use, rather than through some separate development toolchain and skill set". So unless programming with Rust was a normal part of the use of the software, anything which involves editing Rust code wouldn't be allowed.

That basically means pushing the logic out of the code and into the data. One example would be old versions of Microsoft Office, the toolbars were fully configurable by end users, even down to drawing new icons and linking those buttons up to VBA macros to provide new functionality. It could be controlled through user-editable data, rather than having to re-compile Office.

There's always a tricky line between code and data, in Lisp the line is very blurred. Configuration data is another classic place where the line is sometimes hard to pin down:

Most contemporary applications fail to meet all of these, leaving us with no pathway towards improvement. The only option is to plead with the app developer and hope they will deign to grant your request. As the importance of computing in everyday life grows with each passing year, we must fight for these values to ensure the power of computing is evenly distributed.

On the other hand, if users could be asked to learn Rust (reasonable if you're writing library code or developer tools, as then your users will be other developers) then open source addresses that pretty well. If an application is shipped as source code, then the user can make changes and hit cargo run to use their new version. The Rust build system is very easy to use, lowering the barrier to users that want to make just small changes.

We argue an even more radical level of customisation is required: it must be possible to extract arbitrary bits of user interface, logic, and data for recombination in a new environment. If I want to grab a UI control from one application, some processing logic from another, and run it all against a data source from somewhere else again, it should be possible to do so.

To do this with Rust, the answer is to package up these components as Cargo crates: they can be freely recombined, and even modified by replacing a crate with a fork in Cargo.toml.