Rust does have one glaring weakness: compile times. I suspect in the LLM era we will see the rise of a language or perhaps some sort of Rust redesign that achieves what Rust has with great performance and great type safety but also has better support for fast compilation.
I have found that agents are good at writing Verus proofs in a Rust code base, and that these proofs have only a minimal negative effect on the normal compilation path. I have a skill for using Verus: https://github.com/gregwebs/skills-sdlc/blob/main/skills/rus...
Compile times are really only an issue of you need to iterate extremely fast.
One of my spare time projects is a "prompted" 3D modeling app that is now (incl sub-crates I maintain) about 500k lines of Rust.
The link stage is the longest. An incremental build (w. sccache+mold) where I changed a few source files is done and runs after maybe 20s max on my 2022 Rhyzen 6800H-powered laptop.
I think this is acceptable when working on that kind of project.
For games where this matters I usually prototype in some other language first, TS, Python, Lua, whatever then translate to Rust when game mechanics and magic numbers are settled.
Or you simply put those into a config file that gets watched by the game.
At work we have an image manipulation crate that takes like 30mins to 'dev' and about an hour to 'release' build.
The WASM version takes even longer, about to 2h and needs like 55GB RAM during build.
But that crate has only to be built once a month.
And if it mattered we could split it because it's a metacrate made of ~20 sub-crates.
Yeah, it would be nice if Rust were even faster (I remember compile times almost a decade ago, when I started using it)!
But I think for the typical use cases where you would (should!) reach for it, it's quite ok already.
And if not you can work around it quite painlessly.
I think we could step back and make a list of programming languages features that are helpful or harmful to LLMs writing code. I don't have a complete list, but things I've thought about:
Useful error messages at compile time
Fast compilation to iterate and fix those errors
Efficient memory, CPU, and maybe GPU at runtime
Familiar from the training data [0]
One obvious/preferred way to do things
Explicit types
Rust hits some of those, but not all. I can't think of a language that hits all of them, but a lot of people sure love to rationalize why their own favorite language is the best choice. LLMs don't need syntax sugar and other niceties, and any errors postponed to runtime are a burden on you, not the model.
We could add a few more rarely seen features to increase confidence in the results and make future modifications or switching models go better:
Required pre-conditions and post-conditions
Enforced limits on function or method length
Mandatory test cases
Enforced naming conventions
Lean style proofs of correctness? (probably not)
I'm on the fence about things like linear/affine types for memory management vs garbage collection. Obviously you want memory safety, but there's more than one to get that, and I don't know that you want to force contortions to build simple data structures.
[0] LLMs are very capable of programming in languages they've never seen before. I've had them write programs using my own toy compilers for my own toy languages. However, you waste a lot of prompt tokens up front explaining things, and then they waste a lot of thinking tokens trying to get it right. Any new language would have a chicken and egg problem here, but LoRAs and model refinement could bridge the gap.
I think C# wrapped by .NET does hit all of your requirements. Might need a bit of work bringing compilation time down on enormous codebases, but for 95% of projects 95% of the time, compilation takes only a few seconds, which is fine in the context of an LLM which takes dozens of seconds to reason.
Error messages are mostly useful; compilation is quick (relative to an LLM); memory is not really optimal in most cases, but it's "good enough" and the language puts up a lot of guardrails around the programmer to keep them on the path to accidental success; the training data is full of .NET code; there's a well defined set of ways of working & best practices with .NET; types are explicit.
I've been "coding" a couple of apps with agents + rust recently and I realize how terribly huge the target/ folder can grow. Then, you run cargo clean, get a clean disk but compilation takes forever again. I routinely run out of disk space.
I wonder if „hard“ languages like Haskell will make a comeback with LLMs, because the short term cost of learning the language isn’t that significant anymore contrasted with the long term benefits of the type system and better structure.
What makes languages like Haskell good is exactly benefits you acquire due to learning various abstractions which allow you to write better code. For example I like for an LLM to write code in Haskell using higher order algebraic effects, it's really great for readability but you still need to have some notion of what they are to use them. LLM won't program using them just by itself it needs to be deliberate instruction.
My new favourite thing is to use records to type interfaces for more C style libraries with lots of IO. The trick is to use Generic and a type class to gather the interface into a list or similar and running that in IO using the library. Say, using a record to type audio and midi inputs and outputs in an audio plugin.
Opus can do this correctly first try, you just need to give it the idea!
I sometimes ask an llm to plan out an algorithm or concept in Haskell. Then I ask it to implement it in rust. I think I get a better implementation that way - though I might just be fooling myself. They seem to find simpler abstractions if you start there.
I have used LLMs a ton with Haskell! Opus knows Haskell really well, and it can do things very quickly in it. And in my experience the code it produces has very few bugs.
In my limited experience with OCaml, Opus has problems using the paradigm correctly. For instance it sometimes avoids recursion when it obviously fits.
I think everyone is focused on the wrong future, it is like watching folks arguing about which Assembly ISA variant is more relevant in the presence of optimising compilers.
The hard reality is none of them.
We will have some kind of type system/profs to help drive LLMs output, and those that still will have a job as system architects or whatever, will generate applications directly.
And just it happens with optimising compilers, there will be a way to generate some kind of intermediate representation, like the -S switch, but that is it.
Generating source code for 3 GL languages is an intermediate step.
Who thinks otherwise should spend sometime looking into papers of AI role in compiler development.
Yes, and there's a good chance that will be Rust, at least in the short term.
You can't realistically write a whole program in Lean. So you want a good type system that combines well with a prover. Rust has a good type system, and annotating unsafe sections with proofs is becoming common practice in Rust. Right now you have to choose the proof syntax among several alternatives, but there are efforts to unify.
That's the future of Rust in many companies, agents or no: unsafe code must be annotated with proofs to eliminate undefined behavior.
Now certainly a purpose built system may be better than adding annotations to an existing language, but it'll probably work better if that happens after people & agents get experience writing the awkward combination.
I'm working on a fully memory-safe (LLVM) compiled Lisp dialect with a system Fω type system. Borrow checking is actually far more extensive than Rust and in fact all memory operations are required to be proven safe at compile time (either by the compiler, and if not possible, by the source code via appended proofs). Fairly stable at this point, in benchmark performance is tied with C/C++ even exceeding it because of more aggressive autovectorization and native vector types
For instance
; Sysv native vectors. Initializer values require matching [].
(mut x (the v64 [10 20]))
(set x (+ x 5))
(at x 0 17)
(print (at x 1))
(print (all (= x (the v64 [17 25]))))
; Parameter and result types can be written inline
(fn add4 ((a w64) (b w64)) -> w64 (+ a b))
(let ((result (add4 (the w64 [1 2 3 4]) (the w64 [10 20 30 40]))))
(print (at result 3)))
You also get full fp primitives
; helpers reused below
(fn inc (x) (+ x 1))
(fn dbl (x) (* x 2))
(fn sq (x) (* x x))
(fn pair (a b) (+ a b))
(fn add3 (a b c) (+ a b c))
(fn dv (a b) (/ a b))
(fn id (x) x)
(fn zero (x) 0)
; |> : pipe a value left-to-right through functions.
(print (|> 5 inc dbl sq)) ; => 144 (sq(dbl(inc 5)))
; >> : left-to-right compose; << : right-to-left compose.
(print ((>> inc dbl) 5)) ; => 12 (dbl(inc 5))
(print ((<< dbl inc) 5)) ; => 12 (dbl(inc 5))
; fmap / <$> : apply f, then g (same as >>).
(print ((fmap inc dbl) 5)) ; => 12
(print ((<$> inc dbl) 5)) ; => 12 (11 on sysv: (inc (dbl 5)), function-first)
; <*> (and its alias <>) : the S combinator, (f x (g x)).
(print ((<*> + (lambda (x) (+ x 2))) 5)) ; => 12 (5 + (5+2))
; <&> : flipped fmap, a(b x). <**> : flipped S, (g x (f x)).
(print ((<&> inc dbl) 5)) ; => 11 (inc(dbl 5))
(print ((<**> (lambda (x) (+ x 2)) +) 5)) ; => 12 (5 + (5+2))
I also wonder if some deprecated practises and packages will linger in the training data for a long time. I remember the Python 2 to 3 transition. A lot of people parroted all kinds of outdated information on Python 3 and that made people hesitant to switch to Python 3.
I found it amusing I used to push Rust so many years ago not knowing that I’d eventually get everything I asked for. And especially not how it would happen.
Just like many open source maintainers lectured their unhappy users that their broken and featureless software was given for free and they should make PRs instead of complaining.
This is wrong. Training data is almost irrelevant because LLMs can apply cross-language semantic understanding. JS training data applies equally to JS, TS, C or Haskell.
I've been writing rust for maybe 6 years now, and Im very happy i started before the LLMs entered the scene so i had to fight the borrow checker and all that jazz.
Now, I will say im extremely productive with rust and LLMs, and its also comfortable to know that I wont have to rewrite anything to a new language, rust is already the best.
A famous swedish comedian talks about heroin as the "best drug". Where people usually end up and don't want to stop taking.
I've learned rust when llms appeared and it helped me developed while I learned. My use of llms evolved (https://asfaload.com/blog/ai_use/) and is still evolving: I'm currently at a point where I write most app code myself and use llms to review it. Test and doc I like to delegate to llms, and in that I'm the reviewer.
I think I've found the middle point that fits me: llms have an added value, but I think I avoid most of their idiosyncrasies.
Another example of “I like my language and here’s why it is uniquely suitable for $thing” (here AI).
I just asked chatgpt today for research on whether any feature of a programming language which has been identified in studies to make it better suited for agentic coding. Or whether popularity in the data-set has been proven to matter or even cross-language learning (knowledge from one language benefitting the LLM in writing in another).
Aside from popularity, nothing I could dredge up could prove strong correlations with anything else - including types
> And, naturally, I also happen to think Rust is a really good fit for agentic development
To me this is a sad development. AI skynet slop is winning. Does any real human, aside from the fanboi faction, really love "agentic programming"? That is to use prompts to autogenerate text that is source code? I find that both sad and horribly uninteresting. I also stopped reading AI slop generated descriptions - they are just spam, babelfish 2.0 if you will. When I know that the human behind that text, was too lazy to write it himself or herself, why would I want to read that text? That's just a waste of my time.
> But I think Rust is popular for another reason: because Rust happens to be a really good fit for agentic coding.
Ok, so Rust is the perfect language for bots. Wasn't the original idea to be a great language for humans? What is the point here if AI slop auto-generates everything? Why would you need a human here?
> Rust is designed to give “good performance by default”, making the idiomatic thing typically also be the fastest thing. But another key part of Rust is that you have the knobs to eke out better performance when you need it.
Ok but why does this then not apply to C, C++, Java, C#, D? These can not be used rather than Rust? And you also should not run into memory issues with C like pointers - after all, AI skynet slop should generate bug-free code in C or C++ too. So I don't get why Rust would be THE ultimate slop language here. To me, if AI works, then any language can be slopped down.
This reminds me of the incredibly sad presentation DHH gave on a rails-conf, aka now slop-conf, where he spoke about how AI will win and how Rust beats Ruby hands down and he only AI-slop-spams now (busy on Omarchyslop). These people don't have a "vision" that is decoupled from AI - they are businesspeople and promo-people, convincing you that AI slop is the future. To me this is very sad rather than ... "exciting".
I don't think "to use prompts to autogenerate text that is source code" is a complete description of how agentic programming works. A very important part of the process is that an agent will not just write code, but also explore documentation, write tests, run those tests, and even do fairly complex integration testing up to and including (for UI based work) firing up a UI and visually confirming features work as intended. Agentic software engineering can be quite powerful properly applied.
Yeah, the big part all these "my language is the best for LLM", miss the part that any language in the world is one paragraph away in a markdown file to describe what the generated output should be.
Also there is the part that why not generate machine code directly, where some always jump to answer "but non-determism!", well we have survived thus far with non-determinism in JIT compilers, tracing GC implementations, PGO metadata outcomes in AOT compilers, integration of machine learning in optimising compiler passes, how shader code executes in actual hardware,... the determinism ship is long gone.
So yeah, sad state of affairs, however the pandora box is open, is like Assembly devs wishing that compilers would just be a fluke and everyone would be shortly back into macro assemblers.
> Does any real human, aside from the fanboi faction, really love "agentic programming"? That is to use prompts to autogenerate text that is source code?
I don't love it, but it's my job now and I would prefer keeping it.
I'm not breaking any new ground with the project I'm in - just serving our users and there's a lot of stuff requiring improvement that would normally take a great deal of time to finish if it weren't for LLMs.
For my own things I would rather not use LLMs, but it's tempting, considering how little time I have for such activities nowadays.
"Aside from the fanboi faction" kinda feels like a pre-no-true-scotsman. What would it look like to you for someone to enjoy it but not be a fanboi? One programmer I really respect has said to me that "LLMs have made programming fun again", and I also find that they are really good for dealing with the kinda tedious parts of programming, the kind of thing that would tend to kill or limit my hobby projects. Does that qualify us both as fanbois?
Rust is fast, both at run and compile time (both important for the speed of the agent loop), its nazi compiler excludes many categories of errors that LLMs might make, the compiler's helpful error messages give precious hints for the agent to iterate upon, it's relatively new so not encumbered with half a century of legacy cruft with obsolete syntax, it has many modern first class features, it neatly compiles into a single portable executable. It's the language that's best positioned to mitigate the issues of LLMs while leveraging their (and its own) strength.
I don't disagree with your other points, but calling Rust fast at compile time is... questionable.
I've been doing Rust full time for the last half-decade and hobby before that, and its slow compile times have always been a pain point.
And I've found its slow cycle around compile-then-test is a real pain point with agentic development. Agents get into loops trying things out, and verifying their results, and they tend to accumulate a pile of tests on top of that (which require periodic cleanup). Forward progress often gets successively more slow and painful as compile times start to dominate most of what the agent is doing.
For application -- not systems dev work -- I've been considering making a move to using something like OCaml instead.
I have found that agents are good at writing Verus proofs in a Rust code base, and that these proofs have only a minimal negative effect on the normal compilation path. I have a skill for using Verus: https://github.com/gregwebs/skills-sdlc/blob/main/skills/rus...
One of my spare time projects is a "prompted" 3D modeling app that is now (incl sub-crates I maintain) about 500k lines of Rust.
The link stage is the longest. An incremental build (w. sccache+mold) where I changed a few source files is done and runs after maybe 20s max on my 2022 Rhyzen 6800H-powered laptop.
I think this is acceptable when working on that kind of project.
For games where this matters I usually prototype in some other language first, TS, Python, Lua, whatever then translate to Rust when game mechanics and magic numbers are settled.
Or you simply put those into a config file that gets watched by the game.
At work we have an image manipulation crate that takes like 30mins to 'dev' and about an hour to 'release' build.
The WASM version takes even longer, about to 2h and needs like 55GB RAM during build.
But that crate has only to be built once a month.
And if it mattered we could split it because it's a metacrate made of ~20 sub-crates.
Yeah, it would be nice if Rust were even faster (I remember compile times almost a decade ago, when I started using it)!
But I think for the typical use cases where you would (should!) reach for it, it's quite ok already.
And if not you can work around it quite painlessly.
Isn't that the point of agents?
I’ve switched one of my projects to Go and it took a day for Opus to do the port and another couple of days to finish the features I wanted.
We could add a few more rarely seen features to increase confidence in the results and make future modifications or switching models go better:
I'm on the fence about things like linear/affine types for memory management vs garbage collection. Obviously you want memory safety, but there's more than one to get that, and I don't know that you want to force contortions to build simple data structures.[0] LLMs are very capable of programming in languages they've never seen before. I've had them write programs using my own toy compilers for my own toy languages. However, you waste a lot of prompt tokens up front explaining things, and then they waste a lot of thinking tokens trying to get it right. Any new language would have a chicken and egg problem here, but LoRAs and model refinement could bridge the gap.
Error messages are mostly useful; compilation is quick (relative to an LLM); memory is not really optimal in most cases, but it's "good enough" and the language puts up a lot of guardrails around the programmer to keep them on the path to accidental success; the training data is full of .NET code; there's a well defined set of ways of working & best practices with .NET; types are explicit.
Love the experience in general except that part.
My new favourite thing is to use records to type interfaces for more C style libraries with lots of IO. The trick is to use Generic and a type class to gather the interface into a list or similar and running that in IO using the library. Say, using a record to type audio and midi inputs and outputs in an audio plugin.
Opus can do this correctly first try, you just need to give it the idea!
It gets it right after a few attempts.
The hard reality is none of them.
We will have some kind of type system/profs to help drive LLMs output, and those that still will have a job as system architects or whatever, will generate applications directly.
And just it happens with optimising compilers, there will be a way to generate some kind of intermediate representation, like the -S switch, but that is it.
Generating source code for 3 GL languages is an intermediate step.
Who thinks otherwise should spend sometime looking into papers of AI role in compiler development.
For example,
"CGO 2022 Keynote: Compiler 2.0"
https://www.youtube.com/watch?v=w_sX9aZoZxg
"Machine-Generated, Machine-Checked Proofs for a Verified Compiler"
https://www.youtube.com/watch?v=Dmt0h99iOmM
Yes, and there's a good chance that will be Rust, at least in the short term.
You can't realistically write a whole program in Lean. So you want a good type system that combines well with a prover. Rust has a good type system, and annotating unsafe sections with proofs is becoming common practice in Rust. Right now you have to choose the proof syntax among several alternatives, but there are efforts to unify.
That's the future of Rust in many companies, agents or no: unsafe code must be annotated with proofs to eliminate undefined behavior.
Now certainly a purpose built system may be better than adding annotations to an existing language, but it'll probably work better if that happens after people & agents get experience writing the awkward combination.
For instance
You also get full fp primitivesBe careful what you wish for, etc
Now, I will say im extremely productive with rust and LLMs, and its also comfortable to know that I wont have to rewrite anything to a new language, rust is already the best.
A famous swedish comedian talks about heroin as the "best drug". Where people usually end up and don't want to stop taking.
The current slop-code though ... I don't think many would miss it.
Others "heroin", as analogy, isn't one convincing to get into the slop addict scene really, in my opinion.
I just asked chatgpt today for research on whether any feature of a programming language which has been identified in studies to make it better suited for agentic coding. Or whether popularity in the data-set has been proven to matter or even cross-language learning (knowledge from one language benefitting the LLM in writing in another).
Aside from popularity, nothing I could dredge up could prove strong correlations with anything else - including types
To me this is a sad development. AI skynet slop is winning. Does any real human, aside from the fanboi faction, really love "agentic programming"? That is to use prompts to autogenerate text that is source code? I find that both sad and horribly uninteresting. I also stopped reading AI slop generated descriptions - they are just spam, babelfish 2.0 if you will. When I know that the human behind that text, was too lazy to write it himself or herself, why would I want to read that text? That's just a waste of my time.
> But I think Rust is popular for another reason: because Rust happens to be a really good fit for agentic coding.
Ok, so Rust is the perfect language for bots. Wasn't the original idea to be a great language for humans? What is the point here if AI slop auto-generates everything? Why would you need a human here?
> Rust is designed to give “good performance by default”, making the idiomatic thing typically also be the fastest thing. But another key part of Rust is that you have the knobs to eke out better performance when you need it.
Ok but why does this then not apply to C, C++, Java, C#, D? These can not be used rather than Rust? And you also should not run into memory issues with C like pointers - after all, AI skynet slop should generate bug-free code in C or C++ too. So I don't get why Rust would be THE ultimate slop language here. To me, if AI works, then any language can be slopped down.
This reminds me of the incredibly sad presentation DHH gave on a rails-conf, aka now slop-conf, where he spoke about how AI will win and how Rust beats Ruby hands down and he only AI-slop-spams now (busy on Omarchyslop). These people don't have a "vision" that is decoupled from AI - they are businesspeople and promo-people, convincing you that AI slop is the future. To me this is very sad rather than ... "exciting".
Also there is the part that why not generate machine code directly, where some always jump to answer "but non-determism!", well we have survived thus far with non-determinism in JIT compilers, tracing GC implementations, PGO metadata outcomes in AOT compilers, integration of machine learning in optimising compiler passes, how shader code executes in actual hardware,... the determinism ship is long gone.
So yeah, sad state of affairs, however the pandora box is open, is like Assembly devs wishing that compilers would just be a fluke and everyone would be shortly back into macro assemblers.
I don't love it, but it's my job now and I would prefer keeping it.
I'm not breaking any new ground with the project I'm in - just serving our users and there's a lot of stuff requiring improvement that would normally take a great deal of time to finish if it weren't for LLMs.
For my own things I would rather not use LLMs, but it's tempting, considering how little time I have for such activities nowadays.
Not quite the advantage in the AI era. Quite the contrary. Dynamic linking is something Rust will have to solve.
I've been doing Rust full time for the last half-decade and hobby before that, and its slow compile times have always been a pain point.
And I've found its slow cycle around compile-then-test is a real pain point with agentic development. Agents get into loops trying things out, and verifying their results, and they tend to accumulate a pile of tests on top of that (which require periodic cleanup). Forward progress often gets successively more slow and painful as compile times start to dominate most of what the agent is doing.
For application -- not systems dev work -- I've been considering making a move to using something like OCaml instead.