upvote
> Rust is a complex language prone to refactoring avalanches

This may be so, but LLMs are great at slogging through such tedious repercussions.

I would say if the language prevents sloppy intermediate states, that actually makes it more amenable to AI; if you just half-ass a refactor into a conceptually inconsistent state, it’s possible for bad tests to fail to catch it in Python, say. But if many such incomplete states are just forbidden, then the compiler errors provide a clean objective function that the LLM can keep iterating on.

reply
This is true in my experience as well. I'd even say it's the most common failure mode of current AI! It "fixes" some problem locally and declares victory, but it doesn't fully address the consequences of the change everywhere, and then the codebase is inconsistent.
reply
I’ve seen Claude address the consequences of a change in a way that honestly was more comprehensive than I would be capable of. But I still agree that sometimes it misses the mark. I think that may be due to “adaptive effort “ which Claude used now by default.
reply
> On the other hand, Rust is a complex language prone to refactoring avalanches, where a small change in a component forces refactoring distant code.

Are you saying this out of personal experience or just hypothesizing? I am working on a large, complex rust project with Claude Code and do not experience this at all.

reply
It can happen like this:

- write sleek operator-overloading-based code for simple mathematical operations on your custom pet algebra

- decide that you want to turn it into an autograd library [0]

- realise that you now need either `RefCell` for interior mutability, or arenas to save the computation graph and local gradients

- realise that `RefCell` puts borrow checks on the runtime path and can panic if you get aliasing wrong

- realise that plain arenas cannot use your sleek operator-overloaded expressions, since `a + b` has no access to the arena, so you need to rewrite them as `tape.sum(node_a, node_b)`

- cry

This was my introduction to why you kinda need to know what you will end up building with Rust, or suffer the cascade refactors. In Python, for example, this issue mostly wouldn't happen, since objects are already reference-like, so the tape/graph can stay implicit and you just chug along.

I still prefer Rust, just that these refactor cascades will happen. But they are mechanically doable, because you just need to 'break' one type, and let an LLM correct the fallout errors surfaced by the compiler till you reach a consistent new ownership model, and I suppose this is common enough that LLM saw it being done hundreds of times, haha.

[0] https://github.com/karpathy/micrograd

reply
You can still use the fancy operators for readability, just use a macro to translate them into the actual code. Very common pattern in non-trivial Rust libraries.
reply
I also work on a large complex rust project (>1M LOC) with extensive use of Claude Code. It is very consistent with my experience. Claude frequently subverts the obvious intent of the system - whether that's expressed in comments or types - in the pursuit of "making the build green", as it so often puts it. It, like many junior engineers, has completely failed to internalize the lesson that type errors are useful information and not a bad thing to make go away as soon as possible. It is remarkably capable, but you cannot trust it to have good taste.
reply
This post has some good examples of this sort of problem: https://loglog.games/blog/leaving-rust-gamedev/
reply
That link reads like an autobiography about his love affair with Rust and subsequent breaking up after pushing the relationship a step too far: into gaming. He has been using Rust much, much longer than me, but I rekcon I already hit most of the pain points he mentions. (And I notice he left some things out, like async.)

I've come away feeling that most it looks fixable - but it won't be fixed in Rust. Some of the language choices (like favouring monomorphization to the point of making dll's near impossible) are near impossible to undo now, and in other cases where it might conceivably be fixed (like async) it won't be because the community is too invested with their current solution.

So we are stuck with the Rust we have; warts and all. That blog post convinced me those warts mean the language should be avoided for game development. Similarly sqlite developers convinced me the current state of Rust tooling meant it wasn't a good fit for their style of high reliability coding, so they are sticking with C. Which is a downright perverse outcome.

But for most of us C programmers who aren't willing to put in the huge effort Sqlite does to get the reliability up, Rust is the only game in town right now. It's the first and currently only language to implement a usable formal proof checker that eliminates most of the serious footguns in C and C++. But I am now hoping it becomes a victim of the old engineering adage: plan to throw the first one away, because you will anyway.

reply
It's very easy to just instruct the LLM to build using isolated crates, to maintain boundaries, focus on "ports and adapters", etc, and not run into this - in my experience.

I haven't had any issues with this getting out of hand on >10KLOC vibed rust codebases.

reply
From the languages that I know, Rust is the only language that I can look at a multi-threaded code and understand it. This stuff being checked by the compiler is a huge advantage
reply
I only used Rust for fun maths projects crunching billions of numbers (else python is easier for me), but I have to say rayon is the most amazing multi-processing experience I've ever had!
reply
> I haven't had any issues with this getting out of hand on >10KLOC vibed rust codebases.

This rewrite is >750k lines of Rust

reply
I don't see any reason why the approach wouldn't hold just fine, if not better, as the codebase scaled. Indeed this appears to be exactly what the author has done, they mention that they made heavy use of crates.
reply
[flagged]
reply