User:Rongzhou/the (w)Rong way to develop software

From Wikibase
Revision as of 17:04, 24 August 2026 by Rongzhou (talk | contribs) (1st draft)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Make it dumb simple, stupid.

Beautiful solutions are simple: well-known import, thin wrappers, zero drama.

If you are participating in a code contest, 100 lines of wrapper around 10 well-known libraries would probably not attract a very high score: you demonstrated your ability to read, understand, and apply docs, but not your ability to do anything exceptionally creative. In this case, if you can, you may as well limit yourself to stlibs and try to write your own dependencies more efficient and focused than whatever you could have imported.

However, real-world software development is (thankfully) not a code contest. You are not rated for your creativity, but your ability to stay boring. The more boring your code is, the less likely it is to break: thin wrappers following expected structures, using battle-tested conventional libraries in expected way to do expected things almost never break. Why? There are countless other software engineers on this planet writing similar code for their particular use case, and the library/compiler/operating system maintainers are well aware of that, so they maintain your dependencies in a way that your code do not break with every version update.

Admittedly, there will be a fateful day, hopefully in the very distant future, that your code will break, because something outside of your control suddenly changed: new users starting using your software in a different way, people working upstream accidentally spelt coffee over their laptop and hectically tried to catch up days of lost work to meet a hard release deadline... Thankfully, whatever the reason, debugging on your side is a structured exercice: 1. if you updated something recently, roll back to the previous version. 2. if usercase has changed, you modify your thin wrappers to call a different function from upstream library, or in worse cases, you install a different library and modify your caller. In all cases you are not rewriting thousands of lines of code because you developed a custom library that suits your old usercase perfectly but does not respond at all to your new usercase.

Use package managers

As we covered in the last section, you will want to import, whenever you can.

In an ideal world where everyone follows Linus Torvalds' "We don't break userspace" directive, you don't strictly need package managers to import. What worked with version 2.1.0 will continue to work with version 2.2.0, and 2.3.0, all the way up to 3.x.x. So, you may as well write down your dependencies, and install them once, then forget about them.

However, in our world, package managers are your necessity. Why? Because even with minor version changes (e.g., 1.0>1.1) that conventionally should break nothing, people modify userspace, often with the good intention to clean things up, and end up accidentally breaking things. So in the end, many software libraries depend on a very particular versions of other libraries, which in turn depends on very particular versions of other libraries. In the most unfortunate case, you encounter a dependency hell, which means two of your libraries require conflicting versions of the same dependency (e.g., lib A wants numpy 2, lib B wants nupmy 3). There is no easy way out of this, even with package managers; without package managers, you are (or at least your code is) as good as dead. Package managers, such as uv for Python, do their best with their complex algorithms to help you avoid a dependency hell.

Don't be ashamed to use LLMs

You may well be capable of writing cleaner, faster code than your LLM models. However, you cannot write functional code anywhere near the speed LLMs can generate them.

Again, real-life software development is not a code contest. No one cares if your code's memory footprint is 100MB or 80MB. LLM code may be suboptimal, but they work, and that's what counts. If your workload permits you to write large chunks of code that could be delegated to LLMs by hand, might as well delegate the work to LLM, and use that time to make yourself a better software engineer: study masterpieces (Git, Linux, Docker...), not necessarily how they were written line-by-line, but how they were structured. Why the architecture is the way it is? Why the modules are divided in this way, not another? Why the userspace looks like this, but not another way? The best software engineers are software architects. They design brilliant architectures that make everyone happy. For coders, every piece is clear and they know exactly what they are doing when they write each function; for users, every command/button is shaped in a way that they feel comfortable and valued; for maintainers, new team-recruits, every module is cleanly separated and well-documented that if anything goes wrong, they know exactly where to look to. The actually coding? May as well delegate to LLMs to save your some brainpower for the next big thing in software.