-
Notifications
You must be signed in to change notification settings - Fork 0
Description
I assume for this writeup that we've a viable strategy to compile $lang to Rust and that it yields a sizeable performance boost. Both assumptions have to be evaluated, but before that we should be sure we actually want that. ;)
I also assume the following compilation steps: $lang -> bytecode and bytecode -> Rust.
The idea is to piggyback completly on rust infrastructure. In the simplest case, a $lang program is a rust project with a build.rs that does either of two thinks:
a.) It creates a main.rs thats a program that, wenn run, opens the actual project (maybe have a $lang-src folder in the rust project), compiles it into bytecode and then runs the bytecode. This would be the normal development workflow. The interpreter has to be compiled once and all subjequent cargo run commands just execute our $lang sources.
b.) It opens and compiles the project into bytecode and then compiles the bytecode into a main.rs. That would be the release mode and the artifact that can be deployed is a pure rust program. It may be necessary that this binary also contain the full interpreter if runtime code execution or other dynamic features are desired.
Libraries are either written in $lang or Rust and are distributed by cargo. From the lib-user perspective both look and behave the same (since the lib code is compiled to Rust). That means that every time a library is added the development-interpreter has to be rebuild.
In essence: A standalone $lang project is not just the $lang source files, but also contains the complete description to build the runtime plus all libraries and it can create a single, self contained artefact that can be easily deployed.
Why is that useful?
Just delivering a few source files and let the end user sort out the runtime (including all nessesary libs) is not really an option. So a bundle has to be created. If we use libs written in Rust this bundle will contain plattform specific binary blobs anyway, so why not just throw the rest of the runtime into it? (thats whats many projects that are written in a dynamic language end up doing anyway)
It also reuses the excellent cargo infrastructure and makes it more natural to gradually migrate to Rust proper.
Drawbacks:
- To make this strategy viable the the runtime has to be quite small so that the cost of delivering it with every app is manageble.
- Potentially exposes a lot of implementation details to the $lang user
- bind our language very closely to rust, which may or may not be desirable
There are two use-cases that i haven't written about:
- Single file scripts where we don't want to create a whole project. There we would
cargo installa global interpreter with all nessesary libraries. - $lang embedded into a rust program. I don't see inherent problems using the interpreter directly, but the mechanics of when and how to compile to rust would need some thought.
I'd be nice if you poke some holes into this idea.