Idea: light weight rust as zero build scripting language with JIT runtime

The Birth of the Idea

Rust compiler is awesome in the era of AI.

But the only problem is, it's too heavy.

Sometimes, I miss typescript + deno a lot.

  • Able to import https://git/foo.ts directly
  • Zero build
  • Type safe
  • Easy patching using import map

Suddenly, I come up with an idea.

The way to achieve this.

  • Why not let rust able to also be zero build scripting language?

Less performance, but imaging zero build + Rust type system correctness!

Just thinking about it already makes me excited.

Target Audience and Use Cases

In the era of AI, rust-repl aim at making rust as zero build scripting language with 100% correctness in fast development.

Trade off the performance of C‑level applications for the rapid iteration of JS‑level applications.

rust-repl should compactible with Cargo.toml.

rust-repl to rust is like

  • node deno bun browsers to javascript
  • python pypy jython micropython ... to python

rust-repl should benchmark script engine performance against

  • node deno bun browsers
  • python pypy jython micropython ...

Including

  • script launch speed
  • script engine speed

rust-repl is likely jit

  • like node deno bun pypy are jit

  • like python is not jit

No goal

  • compare rust-repl script engine speed with C‑level native applications speed

migration

Before

.cargo/config.toml

[build]
rustc-wrapper = "sccache"
$ cargo run --profile dev
...
Hello, world!

After

rust-toolchain.toml

[toolchain]
channel = "nightly-{{XXX}}"
components = ["rust-repl"]

.cargo/config.toml

[build]
rustc-wrapper = "/dev/null"
$ rust-repl ./src/main.rs
Hello, world!

cargo script vs rust-repl

`cargo script` vs `rust-repl`

Not same with cargo script.

rust-repl is zero build.

cargo script is not zero build.

.cargo/config.toml

[build]
rustc-wrapper = "/dev/null"
$ cargo -Zscript ./src/main.rs
...
error: could not execute process `/dev/null /path/to/rustc -vV` (never executed)
...

Additional

Maybe also offer fast patching.

Like deno import map.

{
  "imports": {
    "foo": "https://git/heads/main/foo.rs"
  },
  "scopes": {
    "./legacy": {
      "bar": "https://git/tags/0.0.1/bar.rs"
    },
    "./new": {
      "bar": "https://git/tags/1.0.0/bar.rs",
      "baz": "crates:baz@1.0.0?features=[]",
    },
    "crates:baz@1.0.0?features=[]": {
      "./src/xxx.rs": "./patches/baz_xxx_with_patch.rs"
    }
  }
}

There's ability to run scripts from Cargo:

and there's plan for a fast codegen backend, but the Rust project did not have enough funding to finish it:

2 Likes

I don't think so?

I guess what it does is compile per script to per binary?

I mean, ALL script share ONE binary!

Like mold is fast.

One binary should be fast too.

Tested.

cargo script is not zero build.

The most similar one might be evcxr.

But evcxr might be compile to .so.

Still not zero build like all node deno bun python...

Would be nice to trade off the performance of C‑level applications for the rapid iteration of JS‑level applications, with 100% correctness in the era of AI, and able to switch to performance of C‑level applications at release.

Though perhaps possible, creating a performant Rust interpreter like rust-repl would likely take years of effort, and I doubt that enough volunteers are available and willing to make that happen.

And I specify “volunteers” because most people who contribute to Rust do so for free AFAIK, and if none of those people are interested in a particular feature, it can easily languish for years without progress. There’d probably have to be a lot more demand or commercial support in order for people to spend years making an performant interpreter, when there’s so many other goals for the Rust project in higher demand.

Note that we do already have a Rust interpreter called Miri. However, it runs code around 100-1000x slower than the compiled program, because the primary intent of Miri is to be used for testing code, not running full-fledged programs. (It’s not a JIT or anything.) You wouldn’t get the fast iteration of JS/TS from using Miri; the part where the code runs would become the bottleneck.

1 Like

You won't be able to bypass rustc's type inference (there isn't an option 'take a value, inspect its type and check which impl was intended'): see type-system-vm/src/tests.rs at main · Aurel300/type-system-vm · GitHub as an example of what type inference does.

Rust requires a complex build not because nobody had an idea to make it a lightweight scripting language, but because Rust's goals of maximum performance and correctness pushed it towards having features that depend on very specific compile-time information, with concrete types, and known type sizes. It requires the program being built in a particular way. You can't have "zero build" when the language needs to have concrete type information which is baked into data layouts. It needs to expand macros. It needs to see all relevant trait implementations to properly dispatch method calls. If you try to make the layouts magically polymorphic, it's either going to break a lot of unsafe code that won't be fooled by it, or require very very heavy hacks that will kill the idea of it being "lightweight".

Your proposal is like for a flying car. Why have 4 wheels when it could fly? It's exciting and it would be absolutely awesome if we made the cars fly. There are lots of great use-cases for flying cars. Just make the cars not heavy, with zero touching of asphalt, add easy lifting into the air.

7 Likes

I haven't heard of any examples of lightweighting subset into scripting language for dev.

I have heard of prior art that starting from scripting language into native application for release.

  • For Python, Nuitka translate into C++
  • For Typescript subset, Microsoft research project Static Typescript compile into machine code
  • For Typescript, PerryTS/perry seems to compile to native code

Like person can login same account on desktop, laptop, and mobile.

I'm just drawing a iphone, or ai phone. :wink: