Live data from Hacker News

I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

iurii.net

51–60 of 76 posts

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#51
I recently rewrote a complex C++ program into Rust using the Strangler Mode, all codes are written by AI. Firstly, I split the code into some dynamic libraries, which uses C ABI to interacts with each other. Secondly, rewrite the libraries one by one. A init_xxx function are used to construct a object and a free_xxx is used to deconstruct it. A handle is used as 'this' pointer. In the caller side, write another class, constructor calls init_xxx and deconstructor calls free_xxx. No other code should be modified during the split.

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#52

And ROI of 0?

Not at all. The example was an experiment.

I did because I have a huge legacy code base, a distributed monolith, a few millions lines of code. Ideally, I want to get rid of it.

At this point, I know a recipe to break the monolith, so I finally could eat the elephant piece by piece.

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#53

I recently rewrote a complex C++ program into Rust using the Strangler Mode, all codes are written by AI. Firstly, I split the code into some dynamic libraries, which uses C ABI to interacts with each other. Secondly, rewrite the libraries one by one. A init_xxx function are used to construct a object and a free_xxx is used to deconstruct it. A handle is used as 'this' pointer. In the caller side, write another class…

Nice. Yeah, the general problem is how to divide and conquer. Your method is not always available (it depends on the language pair), in my case, Go packages didn't translate into Rust crates 1:1.

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#54

I recently performed this exact exercise of converting a complex library set from one language into an intermediate state machine representation and then translated into N other languages. It worked well but there's a lot of caveats. I'd highly recommend a direct "port" in most cases tbh, as many bugs are "load bearing" and may not survive the intermediate translation. I speak from experience.

Wouldn’t finding such bugs be considered advantageous? That is unless someone just yoloing the result directly to customer ofc

it depends, obligatory xkcd https://xkcd.com/1172/

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#55
Most important information is missing here.

  * How many lines was the result? Considering how much err != nil and line splitting needs to be done in Go, did you at least reach 30k SLoC?
    * How was sloc counted here? includes comments, blank lines or not? (something like cloc will give a good answer).
  * Performance characteristics of resulting rust, was there an improvement? It maybe appealing to say Rust is Always faster than Go.
As usual these AI coding posts tend to be loose on actual measurements. Don't like it. Granted you can't do too much experimentation with prompting techniques since you're paying per token. But at least you can assess the code that was produced?

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#56

Most important information is missing here. * How many lines was the result? Considering how much err != nil and line splitting needs to be done in Go, did you at least reach 30k SLoC? * How was sloc counted here? includes comments, blank lines or not? (something like cloc will give a good answer). * Performance characteristics of resulting rust, was there an improvement? It maybe appealing to say Rust is Always fast…

Thanks for the feedback. My main goal was to present the idea with an intermediate representation, I didn't payed much attention to the specifics of this translation, it would vary wildly depending on code bases.

65k LoC of Go without comments resulted in roughly 60k LoC of Rust witout comments (code column of the cloc tool).

The error handling is not so different between Rust and Go, in both cases I cannot panic to avoid the data loss. So it boils down to if (failure) return something for graceful degradation. And generally errors in my case (a text editor) are rare, only disk IO, which is encapsulated in one VFS module, everything else, like non-closed brackets in code is expected behavior.

The biggest differences were in third party libraries, UI, markdown parsing — completely different API and paradigms.

> Performance characteristics of resulting rust

I haven't measured. I don't think there's any significant difference between Go and Rust if app doesn't do allocations on a critical path. The reason I started this project was mainly to experiment (now I use similar approach to refactor much bigger legacy code base), and tree-sitter support is better Rust so it seemed like a good fit.

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#57

Earlier quoted context omitted.

This is impressive but it again led me to questions. Porting the fuzzer from Go to Rust to validate Rust is a bit circular, isn’t it^^? Porting a fuzzer bug will hide the same class bug in the code it’s checking, who fuzzes the fuzzer / setup / harness:)? A good standard for rewrites is a differential testing, feed the same input to the old Go app and the new Rust then diff the outputs. Did you do that?

>feed the same input to the old Go app and the new Rust then diff the outputs. Yes, I completely forgot to mention, this is exactly my case. Rune is a TUI editor, so I feeded the same terminal sequences to the old and new apps. It didn't translate 1:1 (I ported core editor first, there were side panels, and different chrome elements) so I instructed LLM to use ttyd (tty -> browser render), Fable then could open both…

The ttyd and playwright is a clever differential way, personally I’m doing the same when it’s about to compare the views (or fix something related to rendering). Good job on that!

A TUI editor’s real output is the bytes stored on disk, while rendering can look identical the saved files might diverge (encoding, line endings, trailing new lines etc). Did you manage to diff that?

Totally agree on the overnight roadmap runs I have the same experience here. The agents have to know how to self-correct and if it’s progressing, otherwise it’s failing!

Re: I used Fable to rewrite 65kLoC of Go in Rust. It cost $400

#58

Earlier quoted context omitted.

Was it the one with the elided null check?

I don't remember the details, roughly it was unexpected invocation of move semantic, causing use after free in a loop. My all-time favourite example is (again, my memory, I may be a bit wrong): for (int i = 0; i at some point limit could potentially become greater than INT_MAX, the compiler decided that i while(true) signed unsigned mismatch makes me shiver

The compiler cannot optimize that into `while(true)` because the original code does not encounter undefined behavior when `limit` is small enough to fit into `int`. What it can do: infer that `limit <= INT_MAX` and use that to optimize the code following after the loop (and in some cases, even the code before the loop).
Post reply on HN