The worst kind of programmer
mikhailian.mova.org
mikhailian.mova.org
I've been in both sides of these roles over the years. I think the problems in the article really seem to be lack of technical design or leadership though, rather than problems with individual programmers or personality types. You can't have one guy leave, another guy come in, have the same issues then blame the people. The process is broken!
At any kind of head count beyond 5+ people, you need to have some kind of framework in place for choosing and deploying technology. You need someone (it could be many someones, or even the whole team) who thinks about architecture at each step of a project, especially the first part. Conversely, your org should try to intercept "architecture astronauting" early and balance simplicity with decomposition and integration goals.
Managing people can be like herding cats. Managing programmers can be like herding autistic cats. But you still have to do it.
The org in the article sounds like it's missing CTO/engineering management.
No mention of autistic cats there as far as i remember!
This but over HTTP of course, I heard it prevents issues with firewalls.
Have I seen a company-made HTTP over an internal RabbitMQ instance that had to de queue messages and call registered web hooks on our multiple apps ? Yes. And when I asked the CTO why we had to do like this, because we were losing all the rabbitmq purpose, the answer was that HTTP didn’t need firewall configuration so that we could spread our architecture everywhere over the internet.
I think the main cause (as you say) is this:
> After all, the management in business environments is usually non-technical
Management in business environments is not only non-technical, it's also non-business. It specializes in managing people and timelines, without a profound understanding of either the business requirements or the technical solutions available to address them.
I don't know how one promotes a culture where management is technical but that should be an important topic to focus on in many (most?) organizations.
Not necessarily. I’ve worked in a company where the CTO itself was encouraging those employees. He established a clear list of goals to achieve to climb to the next seniority level.
To be promoted you _had_ to do stupid shit like hacking the framework (which was Angular so I let you imagine the potential), be the architect of the project, or make company-wide presentations of your original solutions.
Of course, a team full of people hacking things, trying to be the architectural leader and solving old problems with "invented here" solutions can’t really exist.
So you were either in the promoted hackers camp or in the camp of people trying to do their job of delivering value and quality at the lowest cost, which in a CRUD SaaS business means that most of the time you just have to do the old boring things "by the book" that have proven to just work. But if you were in this camp you were seen as underperforming because you didn’t do what was expected but also you were underperforming for real because adding a single API in the back or a component in the front was just a hell of stupid work.
The "high performers" were just the people who created this hellscape because since they invented it they’d be the only ones to have a full mental model of the team’s codebase.
Now I just avoid any company who promotes their team as "the most talented engineers" because it’s either false or worse. I’d rather work with average coworkers who have a life outside computers and who just want the work done by 6pm.
I worked with someone else who didn’t have a computer at home. Their coding style was “write code that I don’t have to support, I don’t want to get emails while I’m sleeping”. They wrote mega defensive and very boring code. Their code never has any bugs, but they took longer to write it.
Enjoyed working with person two, despised person one.
According to management, person two was not known and person one was a rockstar.
It's probably a good thing to do a training/knowledge sharing on in an org (seniors show juniors different ways to handle errors).
Yeah, total closed ticket count is a terrible metric. If closing one ticket in a rush opens two bug tickets, that’s one ticket opened overall. Much harder to track though!
nice. ;-)
I'm sorry, what??!?!?!?
It seems ironic to me because rust is clearly designed much more pragmatically than golang.
The whole article is also ironic because a hallmark of bad programmers is overgeneralizing their bad experiences.
That’s a big “citation needed”. Why is it clear and what do _you_ mean when you say pragmatic?
Frankly I find things like that all the time, the most recent one I remember is my small frustration regarding rational numbers and duration manipulation: https://x.com/drogus/status/1728407593771471226?s=20
Go was designed to specifically address many pragmatic issues at Google, such as slow compile times, engineer ramp up time, language complexity causing hard to understand code, ease of writing automated tooling, and more.
Golang may be the perfect language internally at google for all i know but where it substitutes for python Id rather use python and where it substitutes for rust Id rather use rust.
Ive been serially unimpressed with some of the design decisions, including the initial reluctance to do package management properly, the lack of exceptions and how long it took to get generics. After trying to write golang i always seem to write equivalent code with 30% more SLOC as a result of some decisions that seem more idealistic than pragmatic.
(im also a pretty firm believer that SLOC correlates to bugs, so i view 30% longer code, all other things being equal = 30% more bugs)
I’ve not seen it replace C++ so much - that’s Rust’s job. But a SWE with 2 years of on the job experience shouldn’t be writing C++ or Rust, they should be writing Go or something equally hard to mess up. (Rust might be safe, but it gives you enough power to write truly unreadable code, just like C++ does.)
The two languages are in different niches, and I am curious why they get compared so much. I write Rust and Go, and for the stuff I work on, they almost never overlap.
The article mentions a Java project, btw, so I'm not sure where is he getting his "it's because of the language" bit.
I can't help but think golang is at best in beta version now, and it's too bad companies picked it up (even without generics, lol)
Huge disagree. Working with Golang is amazing to me: you actually get to spend time thinking high level instead of low level unless it’s needed for business reasons. And when you need to think low level, there’s no 100 ways to do, everything is reasonable.
I get shit done fast, efficiently, and writing good code (easy to read, maintain, test refactor and extend) is easy as hell. Whenever I go back to a Go code base I’ve not touched in years, I’m impressed at how everything still works with no trouble at all and how fast it it is to dig in and be productive.
In comparison I’ve recently picked up a React code base from 2 years ago that I was pretty proud of, and… it doesn’t even build anymore. I spent a day trying to fix the dependencies but wasn’t able to succeed yet. I’ve had similar experiences with Python code bases too.
You’re talking about maps.contains as an example and I used to agree with the sentiment, but in the end it doesn’t matter. I sometimes spend 2 minutes writing a contains method, so what? It’s never been a real issue in my experience.
I argue the real problem was in management - two guys working alone and the rest of the team not participating and not learning until late in the game. Adding people to the project at the end of its lifecycle rarely works well. No knowledge sharing and one guy leaves, what can go wrong?
Another problem is not having anything working for a very long time in the beginning. After a week of work the management should have asked for a demo and if nothing was working, they should start questioning the skills of those two „rockstars”.
> The rest of the team observed them in admiration.
They should have been included in building base, they also should spend time learning what state of the art is (since, as article says, they had time before requirements started flowing)
Then we have the replaceability factor. It's not rare for someone to try to secure their spot by making themselves irreplaceable, and one way of doing this is by being the only person working on a project or the vast majority of the codebase. I'm currently onboarded in a (previously) 1-man project and I find myself learning why they designed things like that instead of learning the framework and best practices.
Developing software as a team really means much more time is spent on discussion, writing documentation, reviewing code and explaining concepts than actually writing code. The benefit of this is: Everyone in the team has a good understanding of the code base and can contribute. The disadvantage: Not everyone likes this style of work and is comfortable with so many non conding tasks.
I like to tackle hard problems. I like playing around with new technology. I like to try out new ideas how to solve problems. I started coding since I was a child, around 10 years old. I tend to code many hours non-stop on interesting problems. (Now with family and kids, I'm somewhat limited in doing that, though.) Many people say that they admire how productive I am and how much I accomplish.
Sometimes some of the design decisions of some projects seem to be bad and lead to lots of overhead later. Basically the wrong kind of abstractions were chosen. Other parts of the software are much better and the abstractions seem to be quite nice, but this is not true for everything. (Related recent discussion here: Goodbye, clean code (2020): https://news.ycombinator.com/item?id=38566235)
I often tried to discuss some of the designs with more people, but noone was really interested in this work, so to push things forward, it was still often just me doing the decisions. I think the management just does not want to invest more resources into the software development. After all, the software works and does its jobs, but it's messy and I think it holds us back in some ways. But my manager keeps saying, we are not a software company, the software is just there to solve some problem.
So, how to improve myself? I was trying to improve on basic design decisions of the software. The feedback loop here is very long though, and then difficult to really pinpoint it in the end. I also tried to improve my communication skills, but here it's even harder to tell whether I improved. At least every decision I do is discussed and communicated in many ways.
I definitely learned already that the simpler the solution, the better, as also this article is pointing out. But that comes back to the problem of making exactly the right kind of abstractions, i.e. the right design decisions.
Often I think I overthink some of the problems now to come up with the right abstraction. I want to get back to my older habit to just do things and iterate. But I'm afraid that this again leads to more messy solutions.
This whole article reeks of imposter syndrome. Of course, it must be the case that all the devs who are more productive and impactful than the author are actually secretly very bad, and that the author's inability to understand technologies like Rx, validation and testing frameworks is actually a hidden strength because it makes him some perfectly interchangeable lowest common denominator developer. I hate/hated working with Rx, but it is fundamentally not challenging or complex.
This story is common because the types of people who are capable of single-handedly building large parts of a software product in a short time are naturally the ones who are "hyper-productive" and leveraging a tonne of different technologies and paradigms. The unexceptional "slow and steady" devs are usually not capable of having that kind of impact. When devs like the author do manage to single-handedly deliver entire codebases (e.g. over long periods of time), they are typically just as bug-ridden and unmaintainable as what the "rock star" devs produce.
Ultimately, the onus is on businesses to avoid crutching themselves entirely on a single developer's output. But there are a heap of shitty businesses that have no method for delivering software other than to let singular, highly motivated and passionate developers "go HAM" on the codebase with no oversight. These businesses deserve to fail, and the unmaintainability of the code base after the departure of their key players represents the correction of a market anomaly.
>Then suddenly, the frontend lead quit for greener pastures
What does this even mean? Key personnel do not "suddenly" quit.
I bet the guy suddenly quit once it became obvious that they'd have to maintain a poorly fit monstrosity and management wouldn't support a full rewrite that was badly required now that they knew what they actually needed. And because they probably got a better paid offer from some other place where they could build something from scratch again. Or maybe I'm just projecting, lmao.
That's exactly what is not implied. The point is not the tech. Any tech can be good.
The thing is that while you can be a brillant programmer who makes super smart design choices using the better techs, it's not enough.
If you create a smart and powerful architecture but you fail to document it and then convince, train and onboard the rest of the team, you may be a brillant programmer but you are also a bad team member.
Those people are not wrong, they can be very productive or useful, but you have to identify them and make them work alone, because that's where they strive. And that's where I agree with you when you say it's a management issue.
Those people are frequently really good at abstract thinking, which is a great power for a programmer but can be an issue when you have to communicate clearly a train of thought with other people. In my experience, this can be a root of conflicts between people that otherwise have a good relationship, because it ultimately leads to programmer A thinking that programmer B is over engineering everything and programmer B thinking that programmer A is too stupid.
> When devs like the author do manage to single-handedly deliver entire codebases (e.g. over long periods of time), they are typically just as bug-ridden and unmaintainable as what the "rock star" devs produce.
That's why devs like the author are never asked to single-handedly deliver entire codebases but to bring their skillset to a team that is tasked to maintain long term code base. And maintening long term codebases for a team may imply doing things the boring and simpliest way.
I'm very skeptical about these situational anecdotes where someone with low impact complains about someone with high impact. "I was on a team where the guy who wrote everything left and then everything sucked" is not a compelling vantage point.
I teamed up with a junior developer to deliver a sub-project of the main project cited above at 1/5 the expected cost.
It did not need much documentation.
For frontend, we took the Angular Homes tutorial and morphed it into the CRUD of a dozen business concepts.
For backend, we used NamedParameterJdbcTemplate and skipped most of the MVC boilerplate.
Other team members took ownership of that code and steered it into directions I wasn't even expecting.
I was silent about the worst of us for most of my career, but now with retirement in sight, I really do not give a pluck what others think. I deliver, enjoy my work and call a spade a spade along the way.
Yes, I am a low-impact developer, so let me quote the high-inpact Sir Tony Hoare to mark the point:
Premature optimization is the root of all evil.
That said even frameworks can be problematic, e.g. in the JS world the technology churn rate is so high that I had developers rewrite perfectly fine though a bit outdated React code bases in the latest fad framework. Those developers are dangerous too, they don’t invent their own stuff but they want to always stay on the bleeding edge, which is a recipe for disaster in most organizations.
Certainly, there are many people who overcomplicate solutions - for a myriad of reasons. The idea that therefore it is suspicious to be passionate about software engineering or that one should work as an interchangeable DevOps cog is deeply saddening however.
The truly best are the ones that do very little indeed. We produce software, not objects. You get to save money when you use a good piece of software not when you write it. But they are seen as lazy.
Testing is all you need to produce bug-free software.
In my current job, I was the most versatile DevOps they hired. The guy that got assigned to bringing me up to speed wanted to use shell script to automate infrastructure creation in AWS. The lead engineer wanted to use Java , because the org ships Java code. Both of them had been working at the org. for twenty years. Then a second lead architect wanted to use Cloudformation for AWS, not CDK (which, for a project this complex, would have made sense). We had to negotiate, and ended up writing Python scripts to generate Cloudformation because let's face it, nobody wanted to edit a single .yml file with a hundred thousand lines of infrastructure code and shell-script nested in it. Six months later, the lead architect who forbade us from using CDK (a consultant) came back and said, "we should use CDK, it's so much better than cloudformation and your home-made scripts." I still want to punch him on the face. But! I don't think that any of us is on the wrong when we say "X". We just do it from our best experience. We are paid to listen to the "Y" the others have to contribute, to do "Z" at the end, and to deal with the consequences, all of it as best we can.
The two attitudes represent extremes, and most people will be in the middle. I’m the agitator on some projects, and I’m the voice of caution on others.
This kind of analysis makes it seem like not only a binary system but a one-dimensional one too. People are multi-faceted and each individual fits somewhere on a multi-dimensional space. Some people like to talk to users, others prefer to talk to technical peers. Some like to break down problems into their essence, others like to do literally what they are told to do. Some like to work on honing their tools and techniques, others prefer to learn something once and keep using it forever.
Ultimately you bring out the best in someone if you can get them doing what they like doing. The "best" people in any field are those that are there because they like doing what they are doing. The ones that struggle are those that are doing it simply as a job that pays. A good team will bring out the best in everyone.
Knowing a fundamental language like C++ as well as you do, you’ll be just fine.
Also managers decided to give all decision making power to people that don't even understand code: scrum masters, project managers, product owners, team leads ans so on.
> One largely unappreciated aspect of Scrum is the interchangeable nature of team members.
I'm not trying to argue that encouraging this kind of programmer will result in better software, but if a programmer goes from "difficult to replace" to "easy to replace" by following these best practices, then maybe the problem runs much deeper than these kinds of individual programmers. Apparently following best practices is bad for job security.
I'm all for simpler, communicable code and APIs. But at the same time not everything can be solved with a junior-level technique. That doesn't mean throw a new framework at it, but it does mean explore the problem spaces, communicate possible solutions with the team, choose one, document it, move forward.
Yeah, it is fun to skip some of the steps above, but usually at a big-picture detriment. You need a balance!
Why call out Rust specifically here? CloudFlare achieved the world's first widespread deployment of HTTP/3 thanks to Rust, and they called out plenty of Rust-specific benefits that sped up the development process and provided peace of mind.
Sure, if you're using Rust just because it's Rust, you'll lose sight of the big picture. This can happen in any language.
If I had a choice, I would have taken Go over Rust just because I need a different kind of people in my team.
Both languages are becoming far more mainstream, but they are still in the realms of people wanting to play with 'new' languages.
The correct answer is to choose a language that is maintainable by most engineers you have, and if you need something else for technical reasons, hire the new engineers first - never impose a new language on engineers without very good reason, and definitely not because "It's simple".
It's often not the language that's the problem, but all of the 'clever' ways the 'clever' devs use it.
What if you compare it to Go that fairly recently got a massive new feature that can change how you write code drastically, ie. generics?
const generics, generic associated types
I know they did ship in multiple stages, and some of those were relaxing limitations (once edge cases were accounted for), but a lot of the work was refactoring large portions of the trait solver and related machinery in order to be able to express completely new concepts (const generics are not just "generics in more places", even though monomorphization may make it seem that way).
The reason why they don't necessarily feel like new features is because they fit neatly into existing features, which is a good thing (we don't need another PHP). But they both took years to implement and were huge pain points for a very long time.
Also, their existence does not change how you write idiomatic code. Existing code still compiles and doesn’t need changes. Those features are pretty niche.
This will be true forever, because of Rust's stability guarantees. By this logic, Rust will never have any new features.
Author just wants to push narrative. Examples in article were about something else but he needed to slip it there anyway.
They told or were willing for their leads to start building stuff out on their own. The rest of the team were "slacking off because business requirements were in the works".
They had no review of what the leads were doing. They did not involve the rest of the team in the design and build of the frameworks. The leads, also in the absence of firm business requirements produced highly abstract systems that could cater to many different requirements. The rest of the team couldn't understand it and it was bug prone (and presumably hard to debug).
I assume that these frameworks had to be ready by the time the fabled business requirements were finally produced, so there would be some time pressure to deliver them.
I have no idea whether the leads bear much responsibility here from what was written. I do know that the way they write software is very likely to produce this kind of result.
The example you put forth, namely rust vs golang is great; rust is an extraordinary tool.. in the right hands. So no, it is not for the average programmer. You need years of experience to see why rust is a great language and framework. To understand the why. Instead of ditching the Jedi and the light saber with it would be a better approach to understand how to leverage the extraordinary individual without alienating the entire base team. Define boxes where they can contribute as individuals who own key components.. alone. Team work is not for everyone ;-)
1. This specific person leaning towards being a contractor rather than employee. They are more focused on solving technical problems and improving technical skills, but not learning the problem domain, their company's business model and organisational structure.
2. Never being personally accountable for the result of their work, because the company takes teams/departments accountable, instead of individual people.
Number 1 by itself is not a bad thing. Number 2 will be fixed as soon as this developer works for some time as a real contractor or if the organisation gives him a 1-man project and holds him accountable for it. After that they will learn to make sane technology and architecture decisions.
Out of the four listed qualities:
Ability to find satisfaction in solving abstract problems
Ability to put up many hours of work
Passion in software engineering
Narcissism and self-confidence
Only the last one is actually a problem (and it's the narcissism really, not the confidence). The way the author has laid it out can make it look like "passionate hard-working people who like solving abstract problems" = bad. Which isn't true but it can seem like an appealing proposition if you're not that passionate/hard-working/etc.Demographics doesn't have anything to do with it; it's an attitude problem leading to all manner of manageability and team morale problems. These types of people are unwilling to listen to others and don't consider the needs or abilities of others on the team. They just do their own thing, overengineer things, and knowledge hoard with little or no documentation. It's sad to say but many Ruby developers circa 2011 fit this stereotype because they drank their own KoolAid.
As an analogy, it would be like removing the "big words" from the English language because they are not well understood, but then losing the specificity and expressiveness of having them in the first place.
You could always use those words, and explain the definition/meaning as a side-note, which would be more inclusive without losing the expressiveness.
It's often through explaining the need for a big word, that people realise there are smaller, better known words, that work just as well - they just don't look as 'clever'.
Another choice quote from the fine article:
> One largely unappreciated aspect of Scrum is the interchangeable nature of team members.
In such an environment, it seems prudent to avoid sunk costs of short-lived technologies, and instead try to reduce complexity as much as possible. I understand that this is not always satisfying, and that one wishes it was different. There is joy in elaborate expressions of language.
Mathematics, finance, material science, etc. all have concepts and words in that conceptual space to define ways to solve and talk about problems. To pick one up and build upon it but have it be forgotten/not-understood has the same risk/reward as potentially choosing a short-lived technology. Sometimes choosing something complex is worth the risk, sometimes it's not.
Energy/"talent" would be better spent elsewhere.
(don't mean "talent" as derogatory but everyone has its own definition so it's a bit unclear)
Different strokes, for different folks, I guess.
He's someone who has almost 2 years of work experience before he got his degree, meaning he worked and studied simultaneously. Because he works remotely he doesn't stop at 8 hours, I caught him working on an issue at 11 p.m. on a Wednesday night, with a Friday deadline (I know because he told me). When I told him to stop doing that cause he will drive himself to burnout he promptly ignored me, claiming that ThePrimeagen and all talented influencers endorse such behavior because it's fine to invest in your career early on.
He's only chasing big firms, and wants to hit senior status before 25. He writes internal company tools in Rust, again because the internet influencers say Rust is cool, and not because there are people in the company who know Rust and can maintain it once he leaves the company (which will happen soon because again, he told me so). He thinks that people should get on his level, and that he shouldn't adapt his work to others, and jokingly threw a "people think I'm hard to work with" remark. He had a job interview where he explicitly asked if they reward high performers who work outside of working hours.
His social media profile is pristine. He keeps a blog that writes for his small side-projects or because he discovered how StringBuilder works and has to analyze it. It doesn't matter if a developer would read it, what matters is the recruiters seeing him grinding.
Before you think "this doesn't affect you in any way" let me clarify: Next time someone asks if you have plans to get married or have a kid, this is the person they actually look for. This is why ageism is a thing. It's not because you're old it's because being young you can afford to not work-life balance. I know that because I'm 40 years old and while I'm not in a life situation where I care about work-life balance I'm implicitly placed in the "this guy gets married soon and has a life" bucket by everyone, even if I explicitly tell them I'm a career-focused guy.
It's the stereotyping based on assumptions which are in turn based on societal expectations that really gets me mad. I'm not experienced enough to make claims like OP does "people like him are detrimental to the team", however since this is capitalism and it rewards what managers think should be rewarded then it's clear which behaviors one must adapt in order to bring food to their plate. Worst or best? It is what it is.
In my opinion and experience, development is done by individuals, who are slowed down by the rest.
Honestly they could do without you. Perhaps if they gave those two your salary theid stay.
Now their garbage keeps crashing with stack overflows, and they complain when files are bigger than a few hundred lines.
We accidentally pushed a 10,000 line file once and it brought the entire bus to a crawl for an hour. TEN THOUSAND LINES.
One day, these twerps pushing this stupidity of “copy everything always cause ‘it’s easier to reason about dawg’” are gonna get theirs.
I have no love for Haskell or functional programming, but the problem here isn't FP per se, it's that they tried to jam it into Java.
Don't fight the language or framework. If you are using Java, write idiomatic OOP code. If you want to write FP on the JVM, then start writing Clojure or Scala. If the business won't let you write Clojure or Scala, then do it on your own time and/or change jobs.
Looks like your FP zealots didnt learn how to compromise on that point or how to work with constness in general.
> One day, these twerps pushing this stupidity of “copy everything always cause ‘it’s easier to reason about dawg’” are gonna get theirs.
Making defensive copies is literally item 39 of Effective Java by Josh Bloch.
The Haskell way is to not bother with that shit, because you don't have to.
You need to be careful about stack overflows when you use manual recursion, but in most cases (even in Haskell) you don't write explicitly recursive functions, you call higher-order functions like map, reduce, etc. instead that are written so they don't run into those problems (those are implemented with tail recursion in Haskell, which is eliminated, but in Java, I assume they're implemented with iteration).
So you’re no meant to use generators/discriminators/whatever because they’re too fancy or something?
IMO any language feature, any technology feature that is there and documented in the API is fair game to be used.
The author seems to be suggesting there is some “standard” way of programming ….. not too advanced mind you …. and that anyone who uses more than some baseline set of features is setting up some crazy complex house of cards.
Codswallop.
What exactly is this line below which you’re a good normal sane programmer and above which you’re a narcissistic primadonna who makes write only software.
Don’t write your software for a baseline of barely competent programmer …. write the best software you can according to the project priorities defined by management.
And use every advanced technique you think is right for the job.
As long as you strive for simplicity then whatever you need to get there is the right technique.
The alternative is done stupid set of rules that go through the programming APIs and cross a whole bunch of stuff out, forbidden for being “too advanced”. Silly. You’re a professional software developer, do your job.
Look at the rest of your team, all the other developers that have to work on the product. Write for the average capability of those, bearing in mind that employee churn will mean new people have to be on-boarded.
Realise that code that is 'simple' to you, often may not be to others - you will see it thought your own. The code has to be readable and maintainable by others.
> You’re a professional software developer, do your job.
Exactly. That's not just about churning out clever code and moving on. It's about creating a product that can be maintained by everyone on the team.
Anyone who's had to maintain a 'legacy' codebase knows exactly what this means, as they curse the names of those who came before and the stupid decisions they made... and spend far too long trying to figure out the obscure code ideas they used.
If a new requirement comes in, they will pass it off as "impossible" or give it an incredibly high estimate, when in reality, it just needs a little creativity and doesn't work in their self-imposed limitations of the application.
Not to say these developers aren't useful - they are great at cleaning up and organizing messy codebases, but it can easily be taken to an extreme, at the detriment of the actual goal of the project.
But again - I don't think this even applies only to developers - it is all industries. There are people who optimize things for a better end-user experience, and people who optimize things for their own personal/team work experience. Ultimately you want both once your team grows beyond a handful of people.
Doubly-so if you start invoking terms like 'Dunning-Kruger'. As if they're so wrong and you're so right - there must be a psychological explanation for why they don't see things your way.
Junior dev works in fear and tends not to make a mess
Senior dev knows less code is better than more
Intermediate dev knows about every tool in the toolbox but doesn't know when is the right time and place to put them to use
It's an extra insult to have to follow through on their bad decisions once they leave