I did a quick test on various of my rust projects. Most of them it failed to run, on one it miscompiles(?) causing a test case to fail. The only project I got it to run without issue is a basic actix-web website. It takes a whole 14 seconds to actually start the web server. A clean compile is only 24s for all dependencies, and a regular incremental debug build is 2.3s.
The hot patching is unusable. It takes 11s to compile the patch after a simple change: (Some("hi") -> None), and then relax gets a compiler error when refreshing the page.
The project where it miscompiles only has a few very basic dependencies; a clean compile takes 1.3s, incremental just 0.25s and tests take ~0.1s. Relax takes a whole 1.4s to run the tests (unsuccessfully).
I'm not sure the Rust JIT feature looks far enough along/well maintained enough to actually work with a typical rust program and when it does it sounds like it's probably slower than AOT anyways https://github.com/rust-lang/rustc_codegen_cranelift/blob/ma...
I think it also only does the backend? I.e. you still need rustc to compiler to do everything but the codegen whereas this seems to be the whole compiler portion of the toolchain "Relax isn't a wrapper around rustc or a plugin for LLVM: it replaces both, and the parts of Cargo and the linker in between."
"Viable" in scare quotes, as it should be. Note that the third one you listed is forked from the second one with licensing credit stripped. None of them are actually used by anybody programming anything real. Calling this commoditization is ridiculous. Commoditization of being able to post superficially impressive claims that get upvoted to the front of HN while drowning out content that has >0 value to anyone on the planet, I suppose.
Somehow always, someone somewhere rediscovers that cutting down the time between coding and code execution makes our lives easier and to a degree be able to write better programs.
Perhaps the earliest and best attempt was Lisp's computational model. Since then, the idea manifested itself again[1], again[2], and again[3] in different forms.
This implies that Rust build times haven't been a topic of discussion for the last 10 years. They don't have long build times just for funsies, Rust is completely different from Lisp.
But there's not really a great reason for the long build times. There are plenty of languages that compile very fast. The Rust borrowchecker isn't the source of the bulk of the slowness. It seems to be a combination of language design (e.g. they didn't design it for fast compile times from the start), and implementation decisions. It does seem like there's room for a Rust-like language with Go-like tooling, standard lib, and a focus on development speed.
It remains to be seen whether you can have a useful borrow checker on top of a simpler type system (at least, a type system that's significantly simpler so as to meaningfully reduce compile times). I have my doubts, personally.
Relax runs the borrow checker 'lazily' so it already starts your app whilst the borrow checker runs asynchronous. It's jokingly called 'gandalf' because I think It halts the JIT if it finds a problem.
The borrowchecker is not the source of the bulk of the language's slowness. It takes a fairly small fraction of the total time, I think I remember the number was 5%-15% depending on the project.
The majority of time is spent between the trait solver and LLVM optimization passes. There is work being done to improve the trait solver and to produce more efficient LLIR code from the get-go (so LLVM has less to optimize).
The Rust compiler, while not extremely fast, is not extremely slow either. As an example, my toy compiler is 130K LoC of Rust and compiles in under 7 seconds on a cold build on my M5 Max. An incremental build is nearly instant. So then why is it that so many projects have a minute compile time with far fewer LoC?
The answer: dependencies (My compiler has virtually none, intentionally)
Rust has a very small stdlib, so you are forced to bring in dependency crates, and not just a few. Many programs have 50-100 or more, and they all have dependencies, and so on. Contrast with Go where it has a culture of few dependencies, and those project have few dependencies. Your Rust compiler is doing a lot more work for what appears to be the same program as in other langs, but ultimately is a lot more code (typically).
To make matters worse, cargo does a decent job of parallelizing the builds, but it can only do so a) at the crate level b) only as much as the dependency graph allows.
I love the language, but I'm still not convinced by Rust's skinny stdlib approach. I appreciate not wanting to end up like python where they're having to remove stuff from the stdlib because it has too many batteries and bitrot is a problem, but there's surely a happy-medium somewhere along the line.
I don't write much Go but it seems like it has a good balance when I do.
It may be a bad example, but even in rust generating a random number involves pulling in 6ish crates
The skinny stdlib is always a mistake imo, because if you don't provide it, somebody else will, and it's unlikely to be as nice to work with for your users as a standard library implementation. In the case of C++, for instance, this lead to the boost era.
For all of Python's warts, it at least makes everyday structures and operations you might want to use fairly painless, and it keeps expression fairly standardized. Leave external libraries to build things that are actually interesting, rather than scaffolding and infrastructure that the language vendor is better off providing.
Agreed. I would like to see an extended stdlib of sorts form perhaps taking inspiration from Go or Python. I think it is too late to shim it into the language itself, but it could be like an alternative stdlib of sorts (more like an addendum, not replacing what is already in stdlib). The bonus is it would be precompiled for all platforms so even if doing a cold compile, it just is linked.
100% this. Was playing with the odin language recently (https://odin-lang.org/) and was very pleased at what was included in the std lib while still being a good viable systems PL. And delightful fast compilation time.
I beg to differ. It's not that Rust is completely different from Lisp. PL writers get so caught up with their 'killer feature' which in the case of Rust is the borrow checker, that they completely abandon the other 50% which is the environment.
If we stopped treating the compiler as a one-shot program, we could theoretically shorten this edit-build-test loop by 99%.
The borrow checker is an example of a certain kind of reasoning that Rust benefits from. There's a reason a Lisp can be inspected and rewritten as the process runs, and it's the same thing that makes Rust difficult to rewrite in the same way. Not sure the exact term for it, but it's very easy to have profound nonlocal effects, for example with TAIT (type alias impl trait).
The borrow checker doesn't rely on interprocedural analysis. The function prototype provides all the information needed to maintain lifetime invariants across functions, so given static typing already then interprocedural borrow checking is effectively zero cost at compile time. (Cf. Intraprocedural, non-lexical borrow checking.) So borrow checking is no impediment to dynamically replacing function definitions. And it would be less of a headache for intraprocedural REPL but-for non-lexical semantics. But in a REPL you could always use an interpreter for running a function currently being edited, then compile it down once complete. REPLs are a headache for languages like Rust because of static typing generally, generics, trait semantics, etc.
I built something similar - tbd on maintaining it - but I got Rust Analyzer emitting code and as well as running in the web. This new concept of rust compile daemon is pretty sick.
Rust is a nice language but it’s so heavy. Since our company switched from Go I’ve had to become used to my laptop being burning hot and stuttering whilst trying to do anything during compilation.
yeah, I've been doing some game dev with rust, and the cost of iteration is hugely higher (though it has been worth it so far). Often a build takes 10min+. Something like this project would help a lot if it supported windows.
It is pretty noticeable if you have agents working in subtrees too, a fresh build in a worktree can be like 20min with bevy
AI maintains it, and its developer tooling really. The main use case is hotloading for LLM's to reduce wait-for-result time and to allow applications other be hot-debugged. Pause on panic is one of its main features I use all the time.
Yeah, this is pretty much a textbook example of what AI agents make possible these days: things that are ridiculously ambitious, but aren't conceptually very difficult (or, at least, are conceptually well-trodden ground). Things like emulators, language runtimes, platform reimplementations like Darling, etc.
JITting Rust isn't conceptually very hard: you just take rustc and make everything dynamic instead of static. The only thing that was stopping it before was the sheer amount of effort. Well, now we have a way to reduce that effort.
Its only prompt is 'make a flashy website for this project'. I think it's fine who reads websites anymore anyway. Readme.md for GitHub is the main thing.
Perhaps a cynical take, but I feel sloppy content advertised seriously is enabling a transparent form of cross-domain self-selection which can be interesting to observe from the outside.
For quick iterations it's perfectly fine. Change something, see if it works. If it doesn't keep changing until it works.
In runtimes that provide quick dev loops some developers have continiously running unit testing sessions. They just fire off every few seconds and give intimidate feedback.
The hot patching is unusable. It takes 11s to compile the patch after a simple change: (Some("hi") -> None), and then relax gets a compiler error when refreshing the page.
The project where it miscompiles only has a few very basic dependencies; a clean compile takes 1.3s, incremental just 0.25s and tests take ~0.1s. Relax takes a whole 1.4s to run the tests (unsuccessfully).
I think it also only does the backend? I.e. you still need rustc to compiler to do everything but the codegen whereas this seems to be the whole compiler portion of the toolchain "Relax isn't a wrapper around rustc or a plugin for LLVM: it replaces both, and the parts of Cargo and the linker in between."
https://github.com/haydenflinner/rust/blob/main/PLIRON.md
iteration-focus is slightly there, i.e. fast hotpatching. But been focused on beating LLVM's compiled runtime performance as of late.
Perhaps the earliest and best attempt was Lisp's computational model. Since then, the idea manifested itself again[1], again[2], and again[3] in different forms.
[1]: Inventing on Principle, Bret Victor: https://www.youtube.com/watch?v=PUv66718DII
[2]: REPL-Driven Development, Stuart Halloway: https://vimeo.com/223309989
[3]: LIVE, Live Programming workshop: https://liveprog.org/
Besides your examples, Eiffel, Oberon, Java, .NET, C++ (yep even for it), Cedar, Standard ML, OCaml, Haskell, Prolog, BASIC, Forth
It is a matter of priorities.
The majority of time is spent between the trait solver and LLVM optimization passes. There is work being done to improve the trait solver and to produce more efficient LLIR code from the get-go (so LLVM has less to optimize).
The answer: dependencies (My compiler has virtually none, intentionally)
Rust has a very small stdlib, so you are forced to bring in dependency crates, and not just a few. Many programs have 50-100 or more, and they all have dependencies, and so on. Contrast with Go where it has a culture of few dependencies, and those project have few dependencies. Your Rust compiler is doing a lot more work for what appears to be the same program as in other langs, but ultimately is a lot more code (typically).
To make matters worse, cargo does a decent job of parallelizing the builds, but it can only do so a) at the crate level b) only as much as the dependency graph allows.
I don't write much Go but it seems like it has a good balance when I do.
It may be a bad example, but even in rust generating a random number involves pulling in 6ish crates
For all of Python's warts, it at least makes everyday structures and operations you might want to use fairly painless, and it keeps expression fairly standardized. Leave external libraries to build things that are actually interesting, rather than scaffolding and infrastructure that the language vendor is better off providing.
That said, I missed the borrow checker.
If we stopped treating the compiler as a one-shot program, we could theoretically shorten this edit-build-test loop by 99%.
Can build and iterate on Rust in the browser!
https://dioxuslabs.github.io/rustd/
It is pretty noticeable if you have agents working in subtrees too, a fresh build in a worktree can be like 20min with bevy
It's great to have zero deps, but that's a lot of code to maintain.
JITting Rust isn't conceptually very hard: you just take rustc and make everything dynamic instead of static. The only thing that was stopping it before was the sheer amount of effort. Well, now we have a way to reduce that effort.
Just tell Opus 5.5 to "redesign the UI to not look like AI slop, design it like a human expert designer would" at bare minimum.
In runtimes that provide quick dev loops some developers have continiously running unit testing sessions. They just fire off every few seconds and give intimidate feedback.