Hacker News new | ask | show | jobs
by jryio 21 days ago
Author here, wasn't expecting this piece of writing to show up on HN.

The specifics of Python were chosen only due to the language ecosystem being fragmented and inconsistent while Python remains an essential learning, research, and now ML programming language (it was my first language and I still love it).

My thoughts on LLM generated code have changed immensely in the last 9 months as I've taken on teams and projects through my consulting work [1] as a fractional CTO. Python remains a difficult, flakey, and inconsistent programming language for complex production systems. Most other programming languages suffer from fragmented toolchains and ecosystems: JavaScript (famously), PHP, and even C/C++ to a degree.

Languages with a single way to do things benefit the most: Ruby, Rust, Swift (even). Low entropy is the way to go and convention > configuration seems to pay off with LLMs.

Mean cost of management is more important than specific edge examples "X company run on Y language". I think that 'boring' languages with rock-solid compilers, toolchains, testing frameworks, and package managers make for high return on engineering time and production maintenance.

[1]: sancho.studio

3 comments

> Languages with a single way to do things benefit the most: Rust

I posit that Rust is the optimal language to emit from LLMs unless you have to target web, a specific platform, or a legacy project:

- The required error handling for Option<T>, Result<T,E>, and required destructuring of sum types naturally reduces errors by an order of magnitude

- If it compiles, chances are higher the code is correct. Especially if you're using strong typing.

- The training data for Rust is likely of a higher quality than, say, Javascript

- The resulting code is fast and portable

- You get really nice threading and async, and you don't have to think about the silly "color problem" because the LLM handles it for you.

- Using an LLM takes away any trouble you'd have with the borrow checker or refactoring, or otherwise working in a slightly more difficult language.

- Applications are single binary executables.

Since LLMs let you generate and manipulate Rust code as fast as you would Python, why not just emit Rust instead? It's the least brittle language, and it's incredibly performant.

It's displayed in my practice that LLMs master Rust even as weaker models like deepseek.
Even for the web, Rust is a great language out of LLMs. It was quite surprising given the early performance of Python that Rust does so well. It really speaks to the high dimensional generality of transformer translation models.
>I posit that Rust is the optimal language to emit from LLMs unless you have to target web, a specific platform, or a legacy project:

What would you suggest is optimal for targeting web?

LLMs seem to have an easy time with Elixir and Phoenix in my testing.
> Languages with a single way to do things benefit the most: Ruby

I love ruby - but surely it's closer to Perl and "There's more than one way to do it" - than python which generally strives for "There should be one-- and preferably only one --obvious way to do it."?

https://legacy.python.org/dev/peps/pep-0020/

In practice, Ruby is much more opinionated than Perl, mostly because of Rails being the catalyst to drive mass adoption of Ruby. So you basically have Rails, and then the RubyGems/Bundler package management was pretty linear. There's no equivalent of python2->python3 schism and the package management churn, and more stylistic continuity since ruby adoption is lower and more concentrated in the 2005-2015 time frame compared to python which had greater diversity of adoption and use cases both before and after the Web 2.0 era. I do feel pythons explicit imports and cultural aversion to meta programming win it some points. Overall though it kind of feels like a wash and I still choose the language based on the some criteria I would have used before agentic coding--claude does fine with either.
Yes! It reminds me of the tabs vs spaces argument. Yeah, you have your preference, but as long as everyone on your team uses the same convention it doesn’t matter

The Rails apps I’ve programmed with LLMs seem to work a LOT better than arbitrary python or ruby or JavaScript apps. I chalk that up to “there are a gazillion examples of omiauth in Rails that the LLM can’t really stray off the path. It just works.”

That means I let the agent do things the way it wants to, not because I have a preference. So we’re using turbo and Hotwire and whatever it is it’s doing. And I’m using React for some other problems. Not because I know React, but because the LLM does.

In golf it is said to “let the club do the work”. Over control leads to disaster. Same with LLMs. Not saying let it do whatever but if there are widely baked in conventions you’ll be far better off letting those do the work.

> There's no equivalent of python2->python3 schism and the package management churn

I tried to run a Ruby script recently and got an error about Fixnum. Apparently they made some breaking change to how integer types are referenced in version 3. I had to modify the script to get it to work on a modern parser. How is this not equivalent to the Python 2-3 jump? I don't know the first thing about Ruby but this already told me that it's a language with breaking changes between versions.

(It was the ruby scripts here if anyone is curious: https://github.com/haberman/vtparse/ )

>How is this not equivalent to the Python 2-3 jump?

The same way triping on a small pothole is not the same as falling into a giant sinkhole.

The claim was not that Ruby had no incompatible changes whatsoever.

Correct, even though Ruby the language exists and predates Rails. What -- 80%+ of all Ruby code is Rails? Effectively the largest consumer and producer of the language which I think is a net benefit to your point.

Correct in that Ruby never had a schism and is still massively productive and wideley deployed (e.g. Shopify + Stripe alone represent billions/trillions of dollars through Ruby hotpaths).

Python's general lack of success in this domain is telling and embodies whats I was trying to communicate in the article -- languages with low entropy in syntax, features, ecosystem, and toolchain compound slowly.

My experience has been the exact opposite. Python seems to churn its packaging and tooling at an astonishing rate, whereas Rails forced a centralisation of its ecosystem.
I can assure you that it's not worth your time to have LLMs write non-trivial code in Ruby.

I doubt Python is significantly better.

The problem isn't that there's more than one way to write working code.

It's that there's infinite ways to write working code, and nearly all of them are bad, and any dynamically typed language allows for a lot of type slop that you don't want.

There's a lot more opportunity for LLMs to write terrible working code in Ruby or Python than there is in Rust, for example.

Swift is something that works very well if you enforce Swift 6 + good architecture and doesn’t work very well and ends up with slop if you don’t.

Usually once the project is already established and has good patterns, both Claude and GPT will continue the good patterns, but you may still want to add a review pass step to remove bad practices (usually hacks around concurrency instead of doing it properly).