Write code like you just learned how to program (2010)
prog21.dadgum.com
prog21.dadgum.com
There's a point, a number of lines of code, where unstructured code becomes completely unmaintainable. You can't add to it, you can't change it, you certainly can't understand it. It's just what it is.
Structure, modeling, software architecture, testing, development practices, those sorts of things, these are basically the entrance fee for getting to work on larger problems.
I’ve seen worse codebases by mediors/seniors…
Sometimes I look at a codebase and I barely need to look around to feel at home. How do you grok a codebase while barely looking at it? Convention.
I think it's a repeating pattern. A lot of people with experience writing code but inexperience with software architecture (which is arguably most professional developers) tend to create quite a mess if you task them with designing an application.
Architecture experience is a lot harder to gain as you really only get a few shots to practice the craft, and there's a lot of beginner experts giving some seriously questionable advice if you go online looking for a second opinion.
What's written down tends to age poorly and become prescriptive, that's beyond the fact that a lot of supposed architectural advice is written in bad faith as marketing for cloud- or consulting services.
I think a big part of the problem is that it's all very situational. The same architecture choices may be fantastic in one project and a chronic migraine in another.
My first microcomputer ran a BASIC. The variables in that BASIC were single letters like A, F, X, etc. or a single letter plus a single digit like A4, A7, G2, etc.
Coming back to a program that I had written several months previously was pointless, as I couldn't remember what all the variables were for, or what they did. It was just easier to completely rewrite a program, rather than maintain one.
My next language happened to be COBOL with its variables that could be given fully descriptive names like EMPLOYEE-HOURS-WORKED, ITERATION-COUNT, SALES-TAX-VALUE, etc. Variable names like that mean that I can look at programs that I wrote in the 1980s and immediately be able to maintain them. That habit of giving variables really descriptive names has remained with me for decades.
YAGNI is a somewhat similar advice, and a good one -- at least for my overengineering inclined brain. But if for every single decision you invoke YAGNI, because overengineering is bad, you can also end up with bad code. Even in that case though, the standard for what is "bad code" depends on context (goals, deadlines, etc.). Even "objectively" bad code might not have a significant impact on the project, again depending on context.
Article is from 2010-12-24, posted a bunch of times. Earliest: https://news.ycombinator.com/item?id=2037576
If one can also be humble, and take other opinions into consideration, then that's someone I enjoy working with. I strive to be this person towards others.
And I think all the advice has to be taken through that lens. Of course someone who is in the midst of their programming journey is going to say, "No, I want to do the advanced thing now. I'm advanced."
But if "being a programmer" is a disease one wishes to rid themselves of, then advanced programming is merely advanced disease. And that point is roughly when you start to be able to make the right call when asserting YAGNI, because then you can identify with more clarity when the code deserves to be heavy, load-bearing stuff, and when it needs to be more like "code as an asset" - simple loops and branches that help configure the heavy machinery.
You went through YAGNI. DRY is the same thing. It's often very good advice. But there are certainly limits to DRY... calculating the area of a rectangle from its width and height in two different repositories in the same company probably wouldn't justify creating a library to be shared between them. There's a line somewhere in the middle. Being skilled at understanding what side of that line a given case should fall on is something we build with experience.
I think YAGNI and DRY are at their best as advice when they come packaged together, putting them in tension in order to prompt us to find the right balance and not to blindly follow either one. Taken together, they give us a framework for thinking about one set of tradeoffs. I believe the core of software engineering (and many other pursuits) is identifying the most important tradeoffs and finding a good balance among them. Blindly following advice can get in the way of that.
Examples?
YAGNI is a very abused term. I tend to find when people talk about exceptions to it theyre talking about things which don't actually fall under the header of preemptive features or preemptive refactoring.
The focus here is “reliable”. Let the creative guys mess around, we should focus on keeping stuff clean. If we start becoming messy that’s no good, because it’s all downhill from there. How can you draw skulls, no matter how messy, if the drawing functions don’t work?
Using this article’s story, we are the ones creating the drawing functions, not the “skulls”. We make sure those guys that actually see the skulls can do whatever it is they do. We are bad at that, so when we are asked to be creative we arrive at what the author describes: few lines, something simple, something algorithmic.
That’s not because you are all about cleanliness.. you just lack creativity and vision and an artist’s drive to make it reality. And that’s OK.
Can we stop saying this? Has anyone who said this actually TA’d for an intro programming class? It’s not as beautiful and “straightforward” as you imagine.
- Spawning threads for things that don't need threads
- Using timers for things that don't need timers
- Everything in one file, OR
- Everything in way too many files
- Most of all, busy loops, thread safety problems, and global mutable state.
I have seen the face of student code and it is weeping
What does it mean?
I can understand performing fewer tests in that context, because writing tests can take a lot of time. Still, a minimum number of tests that target complex code is a good idea.
And he agrees with you - "[... if] what you really want to be is a software engineer".
You can still be the designer of an experience, is what I'm saying. There shouldn't be anything lost if writing code properly is what you always do.
I have another colleague who “digs straight tunnels”: long functions, huge if/else’s embed things instead of reusing them.
I’m more like the first guy. Which means I have a lot to learn about simplicity from the second guy. The second guy’s code is easy to modify, because control flow rarely jumps file, or even function. It never ping-pongs messages between actors. He never prematurely optimises or generalises.
I believe it is necessary to reach the center of the bell first to grasp what simplicity means.
Systems & software reward greatly those who can keep a broad mentality, who are excited & happy to investigate possibilities & spring for bigger wins. Too often I've seen teams just grow sour & sad & turn into gatekeepers of code & what happens; it's a social loss & even if some of the ideas would have gone bad I feel like in the balance keeping an agile mind is effectively necessary.
Now even when I am trying to go fast it comes out pretty clean.
Evolution only occurs through mutation.
Those who never mutate, never evolve.
Don't forget the second step, otherwise your nightmares will haunt you...
Next you'll be telling Magnus Carlsen to always capture a piece every move, no matter what.
Ive found this a good way to first understand my solution before I optimize the code. I create less confusing abstractions and more code that’s easy to change. If i try to architect it first I end up always getting the abstractions wrong.
The sort of "excel but in Java" approach, or the no-code lo-code solutions out there work, kinda. They enable the business world equivalent of dropping blood - lots of boxes with if then statements.
But try to repeat the blood dripping (or business process encoded in lo-code). Try to use meta-programming techniques to dynamically tweak or even just print it out in logical sequence for the auditors to look at and you have major problems.
Computing should be topless - at no point shoukd the format of the code / what it represents be "that's it, no more programming with this data structure". And lo-code deliberately does this for strategic reasons, where as the skull blood coder did it for knowledge and experience reasons
And he (?) will have another experience - he will find the ways of being more "professional" with his code, and then he will use his creativity to get what that better structured code affords in the donald norman sense, and he will create something even more awesome than a dripping skull.
Mozart was always going to make great music. Giving him an orchestra and teaching him music theory just added rocket fuel.
Love like you've never been hurt
Sing like no one's listening
Code like your PR won't be reviewed?
10 PRINT$ "HELLO, WORLD"
20 GOTO 10Much later I learned to encode the position information in DATA statements and loop over them. This is an important leap in skill.
Maintaining the balance between quick and dirty and maintainable is one skill that separates the great engineers from the good ones.
So to succeed in being simultaneously concerned with both the UX and the code, just forget about the code. Great advice. Pass.
(With the help of producers who most likely do have a degree in music theory)
Write Code Like You Just Learned How to Program - https://news.ycombinator.com/item?id=2261458 - Feb 2011 (6 comments)
Write code like you just learned how to program - https://news.ycombinator.com/item?id=2037576 - Dec 2010 (51 comments)