Live data from Hacker News

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

iurii.net

61–70 of 76 posts

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

#61

Earlier quoted context omitted.

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).

This isn't complete example. I don't remember the details unfortunately.

But somehow compiler has decided that i <= limit is always true.

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

#62

Earlier quoted context omitted.

Thank you. Yes I would like to hear more about that - I’d be interested to read details about limiting some of its native tool use.

Fable is good at instruction following, so just adding the snippet I mentioned in the post is good enough for the most cases. There is a way to control tool invocations at the harness level when writing skills or agents. Example: ~/.claude/agents/critic.md --- name: critic description: > Plan Critic. Reviews an implementation plan. Use before the implementation. tools: Read, Agent --- For Claude skills, the frontmatt…

thank you!

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

#63
I have rewritten several things from eg. Python to Rust, Rust to Go very recently. The 400 USD is pretty arbitrary as you could rewrite several big projects pretty comfortably with the Claude ~100 USD subscription tier.

In my experience it mostly comes down to the harness (or lack of) that you use. Something like 'superpowers' can be pretty verbose and hash out things for a long time (and use a decent amount of tokens) but the output is pretty decent. The better instructions and the more brainstorming you do initially the better - as the subagents encounter fewer issues.

Without a harness you could try a direct port (prompt: 'convert x to y, don't bother me') and if the languages are roughly compatible you could get a seemingly working port much quicker but likely with major hidden issues. A comprehensive testsuite is obviously a must.

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

#64

Earlier quoted context omitted.

>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 r…

>files might diverge

The way rune works with files minimizes chances of silent corruption. I keep original byte blobs immutable, separately there is a journal (kinda WAL) of positional deltas (inserts and deletes).

So I only need to validate that blob + deltas = snapshot.

Disk IO is encapsulated through VFS, and writes are atomics (write to a temp file, then rename).

Separate virtual rendering buffer is built on top of that. Rune, like Obsidian, renders markdown preview inline, so the same chunk could be rendered as "Header" as well as `## Header` when under the cursor.

All of that makes it quite easy to work with text. The core function is to translate offset in a byte array to line and column and back, which is pure math and relatively easy to test.

Another trick that helped a lot is to use sqlite extensively: blobs, deltas, vfs, redo and undo history graph are all sqlite tables.

I noticed that LLMs make stupid decisions when it comes to data structures, but they understand CRUD and SQL, so I turned all Rune's internals into dumb CRUD.

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

#65

Earlier quoted context omitted.

Fable is good at instruction following, so just adding the snippet I mentioned in the post is good enough for the most cases. There is a way to control tool invocations at the harness level when writing skills or agents. Example: ~/.claude/agents/critic.md --- name: critic description: > Plan Critic. Reviews an implementation plan. Use before the implementation. tools: Read, Agent --- For Claude skills, the frontmatt…

thank you!

I'm glad to help

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

#66

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…

Nice.

It would help to clarify these things in the post. Your software is atypical of common Go software in the wild. The purpose of Go -> Rust rewrite would be usually the efficiency of rust.

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

#67

Earlier quoted context omitted.

Do we think that was necessary? What would have happened if OP had just asked it to rewrite and test/validate each piece as it went until everything is verified and complete? My gut feeling is this is doing way too much, and it would've figured it out.

But we know, Bun was 535496 lines for $165000. The whole point of this experiment was to try and make the rewrite as cheap as possible.

Oh no, bun had quite a bit of machinery: https://bun.com/blog/bun-in-rust#loops-that-write-review-cod...

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

#68

Earlier quoted context omitted.

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 r…

>files might diverge The way rune works with files minimizes chances of silent corruption. I keep original byte blobs immutable, separately there is a journal (kinda WAL) of positional deltas (inserts and deletes). So I only need to validate that blob + deltas = snapshot. Disk IO is encapsulated through VFS, and writes are atomics (write to a temp file, then rename). Separate virtual rendering buffer is built on top…

Nice trick with the structures, good for agent legibility! I will try it out on the right occasion:)

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

#69

I have rewritten several things from eg. Python to Rust, Rust to Go very recently. The 400 USD is pretty arbitrary as you could rewrite several big projects pretty comfortably with the Claude ~100 USD subscription tier. In my experience it mostly comes down to the harness (or lack of) that you use. Something like 'superpowers' can be pretty verbose and hash out things for a long time (and use a decent amount of token…

> I have rewritten several things from eg. Python to Rust, Rust to Go very recently.

What is the scale? Because I'm pretty sure it's impossible to one shot 65k LoC with "good luck, make no mistakes" prompt.

I also did this within a subscription. I counted the number of tokens afterwards and calculated the cost as if I'm paying per token. $400 is of course arbitrary, but it's a ballpark number, bun was $165000.

> In my experience it mostly comes down to the harness (or lack of) that you use.

Yep, it is.

Tokens per task is a good proxy measure of skills, 'superpowers' or any other.

Either a skill gets you the thing more efficiently (less tokens), or you don't need to redo the result afterwards (less tokens). I benchmark all my skills that way.

Models need less and less steering at this point, especially frontier ones.

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

#70

Earlier quoted context omitted.

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…

Nice. It would help to clarify these things in the post. Your software is atypical of common Go software in the wild. The purpose of Go -> Rust rewrite would be usually the efficiency of rust.

I don't know. The most Go software I encountered is IO-bounded, and usualy it's network latency. Rust cannot meaningfully improve this.

Although, in the agentic environment, a benefit of not having GC at all definitely helps.

Post reply on HN