Posted by indigodaddy 1 day ago
When I vibe, it's C# all the way. Not a popular opinion on HN, but the LLMs are trained heavily on the language and are very, very good at it, plus with the 1-file-per-class organization, it can stay pretty clean. I mean, v10 LTS was just released, with all kinds of new language features, EFCore is still the best ORM I've ever used, with full support for SQLite, Postgres, MySql, etc. It just makes writing and reviewing code a pleasure. And the LLMs don't f*ck it up.
> Agents broke that loop in a specific way: the unit of contribution shifted from the patch to the port.
What does this even mean? Every time there's a bug we port the whole code to a different language instead of patching it? This sounds like absolute nonsense, and makes me wonder whether a human actually wrote this.
If you've managed software teams before, this won't be new. You just need to make sure the team does the right things. But you don't want to inject yourself on the critical path of everything. That's micro managing. People hate it and it's counter productive. You need to instead delegate responsibility and check that there is a good process with checks and balances that ensures things are done right.
If you are vibe coding, one shotting, etc. you are essentially operating without guards rails. You won't catch mistakes that are being made. You aren't doing the due diligence of verifying that what was delivered is the same as what was being asked for.
But if you do use guard rails, most of the engineering effort (i.e. your time) goes into building mechanisms to prove that what is being delivered is fit for purpose. And that needs to lean heavily on tools that verify things. Compilers, linters, test suites, headless browser based scenario tests, elaborate benchmarks, etc. Anything you can throw at this. The more the better. Even code quality issues are something you can catch and fix with tools. Code duplication issues are detectable. Poor cohesiveness and high coupling are simple metrics that you can optimize for.
With AI in the mix, all of that gets run automatically and you create a feedback loop where any introduced problem is more likely to be caught early. If you are a good senior engineer, you would have been doing all of this anyway. Because it compensates for your own inability to not make mistakes. With AI, you just need to do more of it.
I've dabbled with a few generated code bases in Go in the last few months. I have about 3 decades of experience with other languages. But not a lot of experience with Go. So, why did I pick it? It's not because I particularly like the language. It all looks a bit verbose and tedious to me and I've always preferred other languages. But since I'm not writing any code, I can step over that and make use of the fact that the compiler and build tools are really good and catch a lot of issues. By using Go, I'm leveraging the tool ecosystem around it. Which is really solid.
Because I don't read/write Go code, I'm forced to treat the system as a black box. Which means I just test the hell out of it in any way I can think of. When I don't know how, I ask the AI to suggest me ways. And it does, and I make it add those as well. My little system has performance benchmarks, end to end tests for everything, scenario tests testing complex scenarios, static code analysis, race detection, etc. And lots of unit tests. If I find any issue, I get paranoid about what else might be broken.
All I do is getting systematic about making it falsify the theory that it could all be broken by failing to produce a broken test scenario. I'm equally paranoid about code quality and technical debt. So, I make sure to check for that as well. Not manually of course. I simply ask the AI tool to do targeted reviews of code looking for duplication, adherence solid principles, etc. Any issues found are prioritized and addressed. With most quality issues, simply asking an LLM to look for such issues is surprisingly effective. Having guardrails just automates these checks and balances and makes them routine.
My inability to review at the line level no longer matters that much. Worse, me reviewing tens/hundreds of thousands of lines of code is probably counter productive. Even in languages I know well, it would take ages. I'd be the slowest part of the whole engineering process.
The friction is that most developers aren't trained to comprehend assembly or otherwise. The vast majority of CS programs don't do it seriously. Many don't really know the difference either, and even I would need a refresher before trying to debug assembly.
I also think token cost restricts directly writing into assembly language. I've experimented with assembly output, as I'm sure many of us have, and can confirm small assembly programs produce more tokens as a result because of the lack of a standard library. However, because tokens are currently priced per million, I don't think it's a significant restraint.
The hops right now are Python -> C -> Assembly . The trend is now Rust/Go/C -> Assembly. Perhaps in the future, there will be nothing in the middle.
Too capable for a job control language, interesting objection, but if a job control language is too capable, it becomes a job implementation language...
Too slow to implement applications. So many examples of big balls of Python code creaking and struggling, slowly. Just one example: my homeassistant instalation running three lights overwhelmed a Raspberry PI 4 causing it to crash once a week.
To me Python is a poster child for "popularity is not quality".