Remix.run Logo
kstenerud 11 hours ago

The killer feature of golang for LLM dev is the tooling.

forbidigo is what allows me to keep ambient config out of my app, and restrict file access to a small set of paths. The coverage tool has "nocover", so you can guarantee that every realistic path is exercised at least once ("100%" code coverage, which is not a marker for testing completeness, but rather for flagging code you forgot to test). Linting is really good as well.

The only thing I haven't found is something to enforce error handling. Rust is better for error paths because you're not allowed to ignore them.

xavdid 9 hours ago | parent | next [-]

> Linting is really good as well.

Maybe we are using different tools (or we've set it up wrong) but I'm consistently surprised at how slow Go's linting is (using golangci-lint). Takes nearly 5 minutes on our codebase after any change (which means I just don't run it locally or in-editor). It's remarkable how poor the experience is after using tools like Python's Ruff (instant) or Rust's Clippy. I'd have expected a fast, default setup that I could tune.

Event JS's Eslint, which runs in actual JS, takes 21 seconds for a full sweep (which I don't normally run, since the in-editor hints are so fast)

It's surprising, because so many of Go's dev tools are so well thought out!

arccy 9 hours ago | parent [-]

crappy third party tooling is crappy. the author of the project just begs for money while only using linters written by other people

xavdid 8 hours ago | parent [-]

Even using staticcheck directly is slow. Just very surprising- do all other Go writers not use a 3rd party linter (and just use `go vet`)?

jerf 10 hours ago | parent | prev | next [-]

"The only thing I haven't found is something to enforce error handling."

errcheck, generally as manifested in golangci-lint, ensures you can't forget to do something with them. It would be odd for you to know about forbidigo but not errcheck as the former is much less widely known; is there something that errcheck doesn't do for you?

It's worth pointing out that "discard this error on purpose" is a legitimate form of error handling, so "enforce error handling" can't really constitute banning that. That's not a Go statement, that's just true in general... it is sometimes valid to just ignore the error, because there's nothing useful to do with it anyhow. I would agree the ignoring should be explicit, but it is an option.

kstenerud 10 hours ago | parent [-]

The rule I set for linting when an LLM is writing code is: Either you adhere to the rules, or you mark an exception with a valid reason.

https://github.com/kstenerud/yoloai/blob/main/docs/contribut...

Poor defaults break systems by a thousand cuts. They seem to make sense when designing the language (more convenient, less typing, etc), but then they very quickly become liabilities as project complexity increases. Go made the mistakes of mutable-by-default and silent-error-dropping, but their cyclical-import-forbidding was a good call.

jerf 8 hours ago | parent [-]

It isn't entirely clear to me how that relates to what I said. errcheck prevents you from dropping errors or catching them but then overwriting them before doing anything else. There's a flag you can twiddle to throw a lint error on using underscore to ignore an error, too, if you're really perturbed about that. I have a personal rule to always have a comment explaining why it's OK to do that that predates AI coding rules. This seems to meet your criteria.

10 hours ago | parent | prev [-]
[deleted]