This quote can be interpreted in an intelligence-positive way, to encourage you to learn by writing the cleverest possible code. Then, when you get to debug it, you will be forced to improve your skills. This interpretation is called Kernighan's lever [1] and it is very beautiful. The alternative is a life of boredom where you don't learn anything new.
[1] https://www.linusakesson.net/programming/kernighans-lever/in...
”Isn’t this a wonderful learning opportunity for all of us”
Debugging time is never a good time to start honing new skills.
It sounds like spaghetti code but even worse because it’s covered with a messy layer of beans and guacamole and wrapped in layers of tortilla.
Next up: some doofus who learned high-order Haskell in middle school, and takes offense of me calling it complicated.
Now that's an impressive logical leap.
When I try something new, usually what I learn is not that my assumptions were correct, but the more interesting part is where my assumptions were wrong. This usually only becomes apparent either when writing the code, or in some of the more interesting cases, when debugging.
I would claim that any clever final result can be accomplished without any need for intermediate cleverness. Things that look clever to other people but are intuitive to you might be OK. Things that look clever to you should be avoided when possible.
It's an endemic issue, core to the problem of poor software.
> My goals used to be to write code that looked and felt cool to myself and others, ... My goals are now to: - make code so easy to read it’s boring
Same for me, and I'm sure same to many of the folks that have advanced past senior level. The problem of other people, other senior people, needing to read, understand, and significantly modify your code is one of the reasons why you can't really advance past senior in a startup. There aren't enough experienced folks that you have to write "up to". Of course the other part of being post-senior is the ability to scale your expertise, but now I'm digressing quite far. Then once you're that advanced, you don't want to take a pay and scope cut to work at a startup. This is a major contributor to startup technical debt accumulation, one that can't readily be solved.
I still do write "cool code", for code that I will only use myself that doesn't go into production. But for all others, I write easy-to-read code. And I review code with that in mind. When comments have a typo that alter the meaning of the comment, I insist that be fixed. Juniors hate me for being too picky. (and I hate them for being too sloppy.)
Remember, the most important part of your job as senior+ is not what you do yourself, it's how you guide others.
What classes as 'senior' that their own coding style has changed that much in 6 months? O.o
> I still do write "cool code", for code that I will only use myself that doesn't go into production. But for all others, I write easy-to-read code.
Good dev. Remember, you are not your audience. Unless you're just writing play-code in which case go nuts and be as 'clever' as you want. :D
> When comments have a typo that alter the meaning of the comment, I insist that be fixed. Juniors hate me for being too picky.
Then they're wrong, and tbh that's not something I'd accept more than once from an employee.
> What classes as 'senior' that their own coding style has changed that much in 6 months? O.o
Your code style can remain exactly the same, and it would still happen. The reason is not that you would write the code differently today, but that you forgot the issues and edge cases that made you write it like that then, and that at the time you focused too much on the writing, not on the reading.
But the wrong lesson seems to be taken away from this. It’s not that all code is shit - it’s that you aren’t good at reading the code yet if you can’t see all the little hairs and bug fixes.
several projects I've come in to - yeah, the code what shit, and yeah, I could do better. And I've done better. By asking questions, documenting the answers, writing sample data, and writing tests.
I get that code can be sloppy, have edge cases, etc. Took over a project that was halfway migrated from CI to Laravel. The migrator had close to a year on this 'migration'. We had not one unit test case, no migrations, no seeders, no integration tests when we took over. What we had was piles of half-baked uncommented model code, over-reliance on magic methods, Laravel/CI models with the same names and method names often being used in the same request but with unintentionally dissimilar behavior.
The 'code' isn't the (whole) problem. All the other stuff around the code that provides the context is the problem. We had ~ 20 tickets in a tracking system with vague notes, and were given 5 email threads of discussion about functionality questions, none with actual resolution.
> it’s that you aren’t good at reading the code yet if you can’t see all the little hairs and bug fixes.
Or... the person writing it before you simply didn't know how to write/document.
Sometimes - really, honestly - you can actually "do it better" because... really, honestly, sometimes you are actually better - more competent, more experienced, more diligent, more professional - than the person who left the code you're working on. Not always, but not never.
In my experience the latter case is far more common. But I suppose experiences will differ dramatically depending on what you work on.
I've advised a number of folks to care less about the code style, and focus more on making it at least understandable. I don't particularly care if you're using a factory pattern or not, but please do doc/comment someplace what the expected behavior for your 'backordering' logic is. I can fix things later if I understand what was intended, vs just what I have to guess at later.
Have worked on some projects in the last few years that are 'bad' from code perspective. One is bad, but the company as a whole operates... decently, and is improving, and more importantly, is providing a lot of value to their customers. The customers tolerate some bugs now and then because a) they still get value and b) the issues are addressed. There's a full process for changes/fixes/rollouts, and the team overall understands that there's tech debt to deal with. Some folks understand that they're still paying off tech debt from 3-4 years ago, and understand those decisions were bad, and try to avoid those same mistakes.
Hundreds of integration and unit tests (growing every week) help grow the confidence levels, and remove barriers to smaller refactoring efforts, because there's a reasonable way to detect the impact of changes. It's not perfect, but that's also understood and accepted.
Another one is the CI/Laravel situation from above. Small company, no real 'tech' people on staff - it's all 'outsourced'. They're frustrated because they see other companies progressing faster than they do, and everything seems to take 5x longer than they expect. It's because the code is bad (on many levels). If we were not trying to make any changes, and it just ran in its current state, it would still continue to make money for them, but they want new features, which requires actually understanding how everything fits together. It took two people several months to have a reasonable understanding of how all the running parts fit together (while also trying to add new features/etc), and finally get a small number of unit tests in place.
I mean really, "this code is unfamiliar therefore it's messy therefore we should rewrite it" is a flaming red flag. Chesterton's fence, people!
This is routine for ordinary cultural practices as well. However, the common explanation for a given cultural practice usually has nothing to do with the actual reasons it might be a good idea.
My coding style hasn't really changed in years - frankly, I don't write a lot of code, I do other things. But I often run into situations where I'm irritated at my own bad code from months earlier, when the shortcomings of the code are actually driven by things I know now that I didn't know then.
Of course you can stall any junior merge request until it looks like senior code, but at that point you might as well write it yourself.
If bad code is getting merged, that's tech debt / time someone else is going to have to spend anyway, plus the time needed to identify the issue and triage down the line. I would think it's better investment to use that time up front and help the jumior level up too.
This happened to me just yesterday! I was helping a co-worker with a problem, and I noticed some redundant code in the same function, so I told him he could simplify it while he was there. His response was, "...but you wrote that". (And as it turns out, only a few days prior!)
In fact, I often conciously refrain from using blame on an "interesting" piece of code because it doesn't matter who wrote it. Looking it up would just satisfy idle curiosity, but yield noninsight into how to improve the code. In fact, I think that blame should just list the commits, but hide the authors by default. "What changed? " and "how?" are always much more pressing questions than "who?".
Pinning bad work on a person does not make progress. Fixing bad code does.
> Legacy code that I wrote myself is hard to read.
Sometimes I don’t even recognize me as the author for a while. Realizing I’m reading something I wrote and can’t understand it without studying carefully has been rather surprising and reminds me of the old Kernighan quote “Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?”
My goals used to be to write code that looked and felt cool to myself and others, to add features in clever ways with as little change to the function signatures and structure as possible so as to not disturb the architecture. While keeping changes small is a good goal to balance, it’s always possible to be too small and add unnamed concepts and fail to restructure around new concepts when you should. Do that a few times in a row (which I have done) and you end up with architectural spaghetti code that might look clean and modular at first glance but becomes a maintenance nightmare. My goals are now to: - make code so easy to read it’s boring, because if it looks interesting, it’s probably too clever - and to identify and name all the unnamed concepts and refactor often to accommodate new features.