Even if an agent generates 90% of the code, each and every diff is going to be in my review queue. Code readability of Python isn't an advantage during write; it's an advantage while reviewing. As an agent generates a piece of code, I will have to read the code, comprehend the code, and determine whether it does what I want. This is the other 10% of the task, and it's the crucial one.
Python is, thus, clearly superior to other languages in terms of ease of review.
This is completely subjective though. I personally find that Python's lack of static types makes code very difficult to reason about. Yes, some devs will write decent comments and name things in a way that's easier to read, but most devs are lazy (myself included) and things get out of hand quickly.
But this is also a subjective opinion, and you could argue that I feel this way because I spend most of my time in TypeScript, Go, and Rust.
When you're writing the code, you know what the types are, as you literally just created/wired/whatever them. Static types become a benefit only when you visit code without that fresh context. For instance, third party libraries are far easier to use when the interfaces are typed.
Static typing holds more ground while making assumptions about contracts between components in huge codebases written by many developers. But in the realm of agents, it all boils down to a simpler question, will this particular function generated by an agent do the job that was requested? Line-by-line readability of Python suffices in this case, regardless of whether type annotations are used throughout.
The pragmatic approach would be to enforce type rules where needed (i.e., when working with Pydantic schemas or in FastAPI routes), while not applying any constraints within the code itself.
[1] https://docs.python.org/3/library/typing.htmlhttps://docs.py...
I will gladly use python's type hints, it's a whole lot better than nothing (IMHO better than typescript), but in it's current form it will always fall short of a language that was designed with strong typing in mind.
1. Indentation is harder to see in diffs.
2. Explicit types give context, and if a project guidelines do not enforce type hints, as many don't, then it's hard to see what happens there.
3. Monkey patching and operator override -- I mostly stumbled upon that with "smart" types like ORM objects. Combined with 2. makes it very hard to review.
So I almost always had to download the change and review with IDE help. So it's not just code review anymore, it's manual testing.
My experience has not been this. Dynamic languages make it harder to figure out things locally, unless someone has done the hard work of adding type hints.
Introduced in 3.5 (2015)
Sometimes they are wrong (as they are more like a comment than a compiler directive).
My first task in any project was to figure out why devs don't have error highlighting on for bad types (often it's "it was red so we turned it off"), but good luck forcing others who don't do type hunting to start doing it when "it slows us down".
I come from a heavily Python background, professionally. I spent the entire first decade-and-change of my career using almost exclusively Python; I know it about as well as a person reasonably can (outside of scientific and ML Python, which I just never got interested in, but that's beside the point).
A year and a half ago I got a job doing Rust. At a surface level, it's about as far as you can get from Python in terms of ease of readability, but after 18 months I'm really reconsidering some of my points of view on the matter.
"Explicit is better than implicit," for example, is something I still strongly agree with, but my definition of "explicit" has shifted a lot in the past year. Seeing which guarantees are provided through mandatory, explicit, strong typing saves a lot of time over tracking down guarantees in MRs while reviewing Python code. If I see a signature as an `Arc<dyn AudioInterface>`, for example, I immediately know that:
- It's thread-safe and memory-managed using reference counting (because `Arc` provides those guarantees);
- It's a type-erased object but is guaranteed to provide all the functionality from the `AudioInterface` trait (which, let's say, could be a supertrait of `AudioInput` and `AudioOutput` -- so it provides both of those);
- It uses runtime dispatching (since it's a `dyn` rather than a generic/`impl T` where `T: AudioInterface`)
I can choose to operate on it by reference with all the caveats that entails, or decide to either `Copy` or `Clone` it, depending on whether that's available for that type and if I can stomach the runtime cost.
All that to say -- Rust doesn't suck to review, relative to Python, in the long run. At first, yes, holy crap, it's such a huge cliff, and I can appreciate your point of view... but there's something to be said about having all this information surfaced as part of the language's syntax and semantics.
Python still has a special place in my heart, and I'd still use it over anything else if Rust isn't an option, but to echo a popular sentiment from other people who've made this migration, I don't know if I can go back to handwaving away whether or not something'll cause an allocation :)
Do we get visual comparisons along with this bold claim?
At some point that becomes less sustainable and looking at something with less abstraction assures you’re at least looking at a baseline source of truth, even if the volume is massive.
There’s going to be a whole world in the knowledge economy, not just software but everywhere, around validation and sign off of information that we’ve taken for granted as a cost prohibitive process where only the best options make it to high levels of function and maturity.
Whether we get better results if AI reviews Python or Rust I'm not sure. But I suspect Rust will win out as the training data likely has more content around Rust correctness and language usage than Python does.
> the trend is AI also does the code review
please no. Keep at least four eyes on all code you ship