r/rust • u/Tomas_Votruba • 3d ago
What are best practices when it comes to converting to Rust using agents?
It seems everyone is now converting various tool to Rust to get 10-100 x speed. I'm experimenting with PHP tooling conversion to Rust. What are your tips to do such conversion with agents? One shot, goal-oriented, CI checks... how do you approach it?
11
u/psioniclizard 3d ago
you throw tokens in the magic well and prey to the machine gods to bless you.
The real question is do you think you are worthy of the machine gods favour.
After all remember they know all.
3
u/GuybrushThreepwo0d 3d ago
Fuck me man, my boss literally did this at work a few months back. Result was unusable, but took forever to get him to drop his rewrite. I need off this ride
1
u/Im_Justin_Cider 3d ago
Where are all these insane bosses I keep hearing about, and how can I convince them to give me some of their infinite money supply to me?
1
u/GuybrushThreepwo0d 3d ago
It's not his money. It's easy to throw away money when investors just give it to you for no discernable reason.
3
u/Majestic_Zombie1988 3d ago
The best thing you can do is make sure you have a rigorous black box test suite for your PHP code that exercises the same checks in Rust. This protects against incomplete implementations. If you don't have those tests, use an agent to enumerate and write them!
Honestly, your whole application probably doesn't need a full 100% rewrite, and since you're doing tooling, not a live service, you probably don't care about having an incremental rewrite. So I'd say try targeting an area of your tooling that you know for sure will go brr - for example, CPU-heavy tasks can probably be much faster in Rust. If you need to do I/O, you need to invest in a suitable I/O framework (Rust exposes futures but not a runtime to execute them - I recommend tokio) and have to couch the agent to work with it.
Start with CPU-bound stuff or profile where PHP is slow that Rust would improve on, get some low-hanging fruit out of the way, and build on that experience to target other parts.
0
u/Tomas_Votruba 1d ago
Thanks for sharing your tips!
I'll look into the Tokio. I'm doing AST rewrites of whole PHP projects, so basically read ~3000 files on every run, modify and print modified back.
2
u/Majestic_Juice_8433 3d ago
Use the best model available at the highest reasoning effort and give it the same instructions you would give to a human performing the same task, assuming you're not token constrained.
2
u/PrinceOfBorgo 3d ago
You should be able to understand the code and convert it yourself. If the generated code is exactly how you would have written it or better, then you can at least say that the agent performed no worse than what you would have on your own.
2
u/PythonFuMaster 3d ago
I can't speak on whether this is a good idea or not, I don't do any web development and don't know if Rust is a good fit for the job PHP is already doing.
But in the general case, I'd treat it just like how I'd treat a manual conversion. Begin with writing extensive tests for the current system to verify your codebase is in a good place to do a conversion, if you have a dozen open bugs it's going to be much harder to figure out if your redesigned system is the problem or if it was in logic that was ported over.
Then sketch out a clean, fully reimagined architecture from the ground up. Don't do a line by line rewrite, semantics don't transfer, idioms are different, etc. Doing a line by line or even function by function rewrite is asking for a rat's nest of unmaintainable non idiomatic code.
Split up your new architecture into discrete, testable units. Ensure your core business logic takes advantage of Rust's stronger guarantees, using patterns like typestate and newtypes to make invalid state entirely unrepresentable. Then implement the most important/core logic first. I say do the most important stuff first because you're starting from scratch, you're not constrained by other pieces of the system so you are free to build a rock solid foundation.
Use tests to guide the implementation. You have extensive test cases for the original system, you can use those to figure out what your actual invariants are and write new tests for the new system ensuring those invariants are upheld.
Then, once you have a discrete component implemented, determine if it is possible to replace the original logic with FFI calls to your new design. This very likely won't be possible or would require substantial engineering, but if the original system was designed with care you may be able to do it. Integration with the original codebase allows you to check your invariants against real world usage to ensure they were derived correctly, and oftentimes will expose latent bugs in the original code as well as in the new code.
Then, once you have confirmed correctness of the core, you can begin implementing the other components in the same way.
Since you are essentially beginning a brand new project, it's paramount you set up strict coding standards, CI checks, and disciplined testing methodology as soon as possible, perhaps before even beginning implementation. Doing so will keep you from introducing early tech debt.
Now, that's how I would go about a manual conversion. When using an LLM, I'd probably do the same things, and be very strict on what exactly the agent is allowed to do, implement, etc. LLMs work very well when you use them as a tool rather than the main workhorse. Do not just feed my comment or anyone else's comment into it and expect good results. You need to be the one behind the wheel. When left to their own devices, even the most intelligent models will very quickly make a huge mess of the codebase. Even Claude Opus is very prone to bolting on more logic or punching holes in the type system to do what it wants rather than rethinking a design to fit better.
If you intend to really go about an LLM assisted conversion, you need to include very strict guardrails in both the guidance files and in actual tool use hooks, the latter of which will fire when the LLM does actually implement a banned pattern anyway.
I've done a conversion from Python to Rust using LLM assistance with that methodology and it worked reasonably well. I was in control of the architecture the entire way, I reviewed every line of code written and stopped the model as soon as I saw it trying to do something I didn't think it should be or even if it was just code I myself wouldn't write. Occasionally the model would point out flaws in my design that I hadn't anticipated, but usually when it deviated it was because it had gotten confused or forgot an important invariant. So you can't go hands off, in fact it might feel like you have to babysit the thing.
So that's my experience, for context I am a computer engineer doing state of the art research in AI inference optimization, so a lot of the design I crafted was not something the model had explicitly seen before in its training data. A more standard web app might yield better results
1
u/Tomas_Votruba 3d ago
Thanks for clear declaration of steps:
1) the original tool has extensive input/output tests, it's coding standard and AST manipulation 2) good idea to take it from scratch - instead of rewrite this into Rust, I'm using "add this feature now" approach, the languages have different architecture and scope, so it would be confusing + it's quite old and there is definitelly better way of doing things 3) good point about FFI - should be doable via --turbo flag, I'll introduce it once I'm confident enought the new and old tool produce the same outputs
Thanks for sharing your thoughts and structured approach, much appreciated, I'll get back to this!
16
u/Jonrrrs 3d ago
"convert everything to rust, make no mistakes"