Software development is a loser’s game
thehosk.medium.com
thehosk.medium.com
This line is packaged to sound really insightful, but is it?
The goal of software development is to create software in support of some greater mission. That mission might be to make someone's life easier, to make money, to advance human knowledge, or many other things.
If I write no software today, I've also written no new bugs. But have I made any progress toward achieving the mission?
Feels like this person is very frustrated with novice engineers writing buggy code and has assumed a gatekeeper role to protect the integrity of the codebases in which he holds responsibility. It may be a necessary role at his organization, but I just don't agree with the cynical and depressing message.
Blaming all your issues on more junior members of the team is a huge red flag, and this article doesn't really offer any insight into how to bridge the gap between "amateur" and "professional" (which, imo, falls on the senior members of the team).
Senior members should set and enforce the standards via best practices, code reviews and setting the definition of done e.g. unit tests, data, deployable etc
Now maybe they did and the other person refuses to listen (not common in my experience), but I always wonder... you can't just make up 'rules' and expect folks to magically write good code because they followed a rule.
And although it took me a while to understand what the author is getting at, I do kind of see his point which in my mind could be summarized as: slow and steady wins the race. Or: In order to speed up (in the long run), slow down (in the short term). Be conservative, be thorough, understand that developer productivity isn’t about that LOC per x unit of time.
One analogy that comes to mind for me is Formula 1. Sure, it would be faster, right now, to just not pit. You would have to drive into the pit, stop and wait for the tyres to be changed and drive out again. Meanwhile your opponents are zooming past you out on the track. But if you don’t pit, soon enough your tyres will be worn down and it becomes impossible to keep heat and performance in them, and after a while longer you might even have to stop completely due to a puncture.
The ‘pitstop’ could be anything that ensures productivity in the long term and as such helps in reaching the final goal, and those are the things that take a professional to understand the importance of.
If that's the goal - the only goal - then all code is equal, and it doesn't matter how it's written. So... go crazy? Use global variables and goto statements? Hardcode path names and don't bother with build scripts? Writing software that works is challenging, but writing software that can be safely modified is even more so.
You gotta think long term (usually)
Practically the requirements are "have software that works, and will be sustainably developed and improved for 5 years". Making the trade offs in terms of "perfect code" to "good enough code" is what makes a software developer (in most settings) go from "good" to "great". Good software engineers can see all the edge cases and future paths. Great software engineers can prioritize those against business goals.
Just like "global variables and goto statements" is bad, so is "perfect, provably correct, and overtested" code in the vast majority of business settings.
Using his tennis analogy, each chunk of code written is like swinging at the tennis ball. You don't have to have the perfect curve-ball, you just have to NOT screw it up.
I've too often seen developers try to attack the ball with the perfect swing and the most force possible, only to have it go straight into the net. If they just focused on getting it over the net as simply as possible, the end result usually means less code that's easier to understand.
Example: junior dev needs to write a data transformation pipeline. They write a microservice and deploy it in Docker on Kubernetes. They do a lot of hand-wringing about reactive design and non-blocking I/O. They end up wrestling with the deploy and getting it done on time. All it needed to be was a simple single-threaded command line utility.
In 15 years, I've seen this story play out tons of times... I'm basically watching devs trip over themselves. I'm not saying I'm perfect either, this has happened to me too.
I completely agree with you.
You need to make something work before you can make it work well. You need to start simple before you dig into the complexity. Sometimes you find that the "stupid" solution is good enough.
I think it also takes experience to see that simple solutions can be more robust; the more natural response to foreseeing future problems (another trait) is to have specific responses for all of them, which generates a complex result.
At this point, I'm extremely unconvinced the problem is just education or juniority/seniority. The "paper factory" is just doing what companies are demanding. The real problem is a general lack of competence being used to market products, be they good when used properly (e.g. GoF, where many readers only look at design patterns and completely forget "composition over inheritance"), or snake oil.
I once had a boss who still coded, even though all the developers begged him to stop. His code was spaghetti, but worse was his inability to come up with more than one solution to a problem. If the first solution he came up with was complicated and error-prone then that's the one he proceeded with.
> You need to make something work before you can make it work well. You need to start simple before you dig into the complexity. Sometimes you find that the "stupid" solution is good enough.
100% true.
People love to dig at Test Driven Development, but it solves a common problem and is great for junior developers because it has 3 important rules.
1. Understand your requirements. And not in a wishy-washy hand-wavey way. But in an explicit, expressed as a single test verifiable/falsifiable requirement.
2. Implement the simplest solution that meets your requirements. Don't over-engineer anything, don't chase the latest fad, don't sleeve solve a way more complicated generic problem that you think we'll hit later, because you don't have enough experience to know how likely we are to hit it and the costs to make that tradeoff.
3. Keep you codebase clean and well factored. Don't let cruft and hacks build up.
Ignoring TDD, any junior engineer that can consistently exhibit those three behaviors is almost by no longer a junior engineer. Those are hard things to learn as an early coder.
Yes as you become mid-level and senior you should be more independent and break the above often - but at that point you have good foundations and the experience to make the tradeoffs to know when to deviate and by how much.
TDD is a very effective method for solving a problem that otherwise often takes a while to solve. Developing good fundamentals.
I feel obliged to mention that this very often goes against "do the stupidest thing that will work".
Most of the time in my career a clean codebase has naturally led to an intelligent solution which is definitely not the stupidest thing that will work.
Finally, it's also often the case that stupid code requires exorbitant amounts of comments or documentation, undermining the notion of it being simple to extend (which many conflate with the original premise). A little bit more intelligent code is usually self-describing.
I'm sure there's some range of nuance to your point, but it's also in line with the iterative philosophy isn't it? Do you find patching/revising things later to skew better/worse or some other downstream consequences?
It seems like you find that approach more efficient overall?
The whole point of design reviews, code reviews, senior devs, and more is to ensure that stuff that doesn’t work or can’t be maintained doesn’t get deployed.
That part (especially the second: maintenance) is endlessly contested in calls until some of us just give up and let the others reinvent the wheel for themselves because they don't listen to experience.
I think the article is saying we should focus on tooling that makes natural human errors less likely, instead of trying to focus on writing more code: in other words, write less code, ship it once without errors, instead of writing more code and having to go through the dev to prod feedback loop repeatedly. The tooling that helps you do that are DevOps practices, testing (and testability), simpler/more conservative design, and some time spent thinking about how to construct the software (or reconstruct it, when modifications are needed).
I wonder what his recruitment pipeline looks like where 80% of engineers end up not being productive.
Sounds like he's hiring wrong to begin with.
I'm just wrapping up a client upgrade that I quoted 80hrs to do. What my Project Manager heard was "Install will be in 2 weeks" and promised client delivery for that timeframe.
What was forgotten was that my changes would take 80 hours, but development doesn't work that way, it never does. What happened is once I cracked the codebase open I found vast chasms of code missing. Whoever had written this project before me wrote no tests, and basically brute forced features to work. A dropdown box that loaded options dynamically based on other user selections had 18 variables buried in the code where 8 of them were either unused or redundant. For a fucking dropdown box?
I told the PM 1 week in that I'm not going to make the delivery deadline and he should be advising the client of such.
---
I don't want to talk bad of my coworkers so I'll just say this. I'm the only developer in my company with a software background. Everyone else is electrical engineering/tech and it shows when you review their code. Comparing this "Amateur" vs. "Professional" article to what I am currently going through feels almost cathartic knowing this is something widely experienced in the field.
I truly love my job, but some days, like these last days, really make me want to unplug from the world and go live in the wild because not only do Amateurs make these mistakes, they're also blind to the Professional ways of approaching work. It almost felt like an argument at times convincing him that this "extra" work that was neglected previously is necessary and should be factored into everyone's projects, not just mine.
Sounds like giving the time estimate before cracking open the code base may have played a role in this. You (and your project manager) should factor in research time before giving your estimate.
If you are expected to give accurate estimates without research, something might be very wrong with the expectations being put on you.
It seems like both of these things should be equally obvious in software.
Every piece of software is different. By the time you know what's going on in there, you're almost done. You have to look, but you're still going to be making a lot of assumptions. Assumptions that can throw you off by a factor of 10 -- or even make the fix literally impossible.
That doesn't mean we can do without estimation, even in software. You have to make plans and allocate resources. Just be prepared to change the plans -- and make plans that can accommodate the changes.
The other half of it was my changes were entirely to the Database and SCADA software, I did not need to touch the PLC software for these features, but I did need to simulate the PLC code to test my new changes. So when it became time to run code in the lab, I found the PLC code was lacking all the proper simulation/test code needed to run it in a lab environment. Basically simulating field I/O such as motor statuses, sensor status, etc. So all that means whoever wrote this project last neglected to include what's seen as standard for our development process and I had to fill the gaps. Its easy to say "this is going to take longer because whoever came before me neglected to test their code" but that doesn't solve the problem we arrived at.
If this was a common issue, I'd pretty much be handing in my resignation, but I'd say this is more of a recent issue where we've taken on too much work for the resources we have. What's happened is coworkers are skipping the stuff like simulation test code because its not customer facing to get to the next project and its not discovered until its too late. If every quote I needed to give included ripping apart every part of the project, even stuff I'm not about to modify, we'd be in a much darker place.
Most devs switch jobs in 2-5 years (or at least that's the common advice given). So the incentive is to play musical chairs, and hope that you've moved on by the time the music stops.
Software has also been such a new field that it was the startup that moved fast and broke things that got the prize rather than the slow but stable company. I think this is changing (lower barrier to entry and ever-increasing complexity). But the momentum still exists.
I chewed through tickets and regularly had an above average point score every sprint, even as a brand new junior developer. I sometimes had the highest on a team where everyone else had 5+ years of experience, which should have raised red flags. Heaps of praise though.
And I was doing it by taking the most direct path to it working without really knowing the potential consequences (which I didn't understand at the time).
The guy who wanted to do refactoring didn't get his contract renewed as that was not productive work.
I know because I did, multiple times. It’s futile. Your best move is to leave in that situation.
"Amaterur vs professional" feels "Good vs Bad" for me but real life is never as simple as that.
It's fascinating to see what people are doing with old hardware like Commodore 64, because it's understandable and doesn't change at this point. If we can use hardware that is almost 50 years old, why are cycling through things so rapidly?
Not their fault either, because maintaining old code is hard, frequently will introduce new bugs, and potentially halt business. Less hope for migrating into newer engine / language.
It's simply that software development is hard and we lack standardization more than any other industries.
But when those same devs go up the chain to improve practices or clean up tech debt, they rarely end up happy. I think that's because executive turnover is also fast and the rewards for underinvestment are much larger. Executive compensation is often tied to stock price and other short-term metrics, and executive tenure is also quite short. That gives them a strong incentive to cut anything that pays off over the long term.
Which I think ties back to his professionals vs amateurs thing. One thing that distinguishes professionals is standards. Doctors won't prescribe you anything you want. Real engineers will refuse to build things that will collapse. But a lot of devs are more minions than professionals; if the boss says to build X, they'll build X. Whether that's good for the company, the customers, or society isn't relevant.
"In order to release feature x which customer y cares about, we need to clear up tech debt / refactor z" is a much better way of getting execs on board.
But I think it's also worth orgs getting to the point of defaulting to just cleaning up after dinner, and also cleaning as they cook. Having to have a specific, urgent reason to clean up a mess is a fine argument for 13-year-olds to make as they come to understand how a household works. But it's tiresome when nominal adults refuse to accept that the future eventually arrives.
You can go all petty on minor idioms and force everyone to use all the sonar rules and all it will create is a lot of busywork with zero improvement on maintainability. And I have seen this dynamic to happen more then once.
The most effective thing we can do to write better software is to get good rest, reduce stress in the work place, and learn to write and communicate effectively. After that comes skills with the tools and processes around writing software: technical, mechanical skills that can be taught and managed.
You need a mix of people from different skill levels to make an effective team. "Amateur," or "junior," or whatever you classify folks with less experience as bring a lot of energy and enthusiasm to a project. They're often eager to learn and many don't know what isn't possible yet and bring fresh ideas to the table (not every idea is a good one but it's nice having folks on your team who are keeping everyone out of a rut). On the opposite end I don't think you can have "senior" or "professional" developers without anyone to mentor or train and work with. In order to solidify your understanding of a topic you have to be able to communicate it to an audience with less specialization and understanding than you. Knowledge takes time to develop into facts we can take for granted.
Update: If you're interested in empirical evidence of the effectiveness of various software development practices, a handy, light resource: https://www.hillelwayne.com/talks/what-we-know-we-dont-know/
tldr; very few practices we eschew as a professional obligation, like being diligent about writing unit tests, have little evidence to support their effectiveness in reducing errors. The things that do work: sleep, low stress, writing, and probably code review.
>Why do I say this?
>Amateur software developers dislike
Is that a thing / the problem?
I appreciate that laundry list can contribute to writing good code, but I kinda wonder how much that has to do with it vs ... just not writing good code, for some other reason (time, bad incentives).
I've only been coding professionally for a handful of years, but I feel like I see a lot of reliance on various ideas and systems to produce good code. Programmers seem to think that they can enforce various systems and ideas to MAKE people write good code . While I think those can help, often I think those are used as all or nothing type measuring sticks.
Personally I think an individual programmer's choices are more (or maybe less) complex than that, as are the outcomes, regardless of some laundry list.
Too many programmers read articles like this and assume that they are the 20% of good programmers while everyone who disagrees with them is the 80% of amateur developers:
> I have worked in software development for 20 years, worked on many projects with many software developers. I estimate 80 percent of software developers are amateurs and 20 percent professionals
Yes, it’s true that some programmers deliver better results than others. It’s also true that some have better methods than others. However, this is one of those situations where if you pulled developers aside and asked them to rank themselves relative to their peers, you might get 80% of people rating themselves as above average and 50% of people claiming to be in the top 20%.
A common pitfall I see is when developers forget that the goal is to ship software and instead focus on doing everything the most correct and perfect way they can think of, regardless of their resources. I’ve worked with many teams of professional programmers who spent so much time perfecting their tooling and code and architecture that they rarely ever shipped anything. Learning the tools of the trade is important, but don’t lose sight of the goal: We need to strike a balance and get work done, not just perfect our craft in a vacuum.
I mean, he's not wrong.. but I always get suspicious if somebody is making up percentages. You know 90% of percentages are made up? (Yes I just made that up)
I get inconvenienced by other people's code all the time, but it's so easy to assume when you're looking at the bug "they should have known this was going to happen / tested for this" when you started your investigation knowing the trigger for the bug.
Anecdotal story: I had a bug a few weeks ago that all sorts of people thought was really dumb / obvious / shouldn't have happened. I checked... the code hadn't been changed for FIVE YEARS. Nearly every customer we had ran this code for five years. Maybe I feel that they should have had a catch for the situation that occurred, but whomever wrote it wrote code that lasted bug free for five years ... maybe they weren't dumb and they knew something I didn't?
Oh man that guy is the WORST.
When I was a junior dev I had a tendency to want to rewrite everything. I remember thinking that most the code I was working on at the time was overly complicated and could be done with far fewer lines of code. Recently I realised I might now be the guy that now overengineers and writes overly complicated code. I think this is common trend for devs too, as you mature you get really good at anticipating future problems so tend to write code that doesn't just meet the current requirements, but can scale into likely future requirements.
I feel like I've kind of gone full circle and now and I'm starting to question if there is a middle ground between the simplicity of writing simple code to solve a very specific problem and the extra time required in writing code that scales. The reason I say this is because I realised devs working on my code often don't fully understand the reasoning behind what I've written anyway and I and the devs working on my code often don't have the time to read / produce documentation explaining the code in detail. I also can't guarantee I'm always available to review PRs and ensure the code quality is maintained, so perhaps most of the time it's wasted effort.
Also often you just don't know what kind of constraints devs are working under. I know for a few projects with tight time constraints I've been asked to do the bare minimum to patch certain bugs or add some functionality so we can ship ASAP. I'll normally push back on this if I feel it's a bad idea, but code quality isn't always the most important consideration.
I realise I'm much more open minded when reading code now because after 15 years as a dev I'm still not sure I always do things right myself.
I've seen this. Huge big O complexity but on a dataset that fits in cache? Runs fine. As soon as the dataset gets bigger, you get systematic timeouts.
Of course most employers probably aren't looking for an "average" programmer, but I haven't found that they usually ask me to rank myself relative to others.
Programming is about doing the fundamentals well and consistently delivering
In many cases, companies just want you to sell yourself and hear the right things. Most companies know they can't hire a senior FAANG developer for $110k.
https://www.youtube.com/watch?v=t4A-Ml8YHyM
"It is possible to commit no mistakes and still lose. That is not a weakness. That is life."
There are so many of these, that they can become a culture majority and bring whole projects to a stop. When i encounter these, i tend to isolate them, link up with other reasonable people (who usually also work around them. If they have grown to powerful, you build two versions, one with their "architecture" (which they will inevitable grab and sink years of time into) and one that will be actually shipped, as a emergency solution.
If discussion is not possible, double the project estimate, cause there are two now.
I'm far, far more frustrated by developers who focus only on shipping software and making dates by cutting corners wherever they can and leave everybody else to deal with their gigantic mess later.
You don't need to cut corners to achieve cost effectiveness and tech debt is just that - debt, which always has to be paid eventually - either through expensive bugfixing, a rewrite or bad user experience.
The project's I've been in that went over budget usually had one or more of the following:
-Too large of a scope vs budget.
-Bad or no architecture whatsoever.
-Increasing personnel instead of reducing scope.
On the other hand projects with an architecture, a set of clear conventions and flexible scope fared much better.
To me the writer sounds more like loser than the amateurs he mocks. But I guess it is on whatever side of the fence you are. Nothing wrong preferring one or another.
I can think of a lot of successful professional teams who for the most part simply outlast their opponent by not making mistakes and capitalizing on their opponents mistakes.
American football for sure often has games turn on a handful of plays.
Looks like this is the Loser's Game essay he mentioned, btw. Also looks like in that essay, it's less about tennis and more about basically doing what the OP did, but applying the metaphor to investing: https://www.trendfollowing.com/whitepaper/the_losers_game.pd...
The hard part in all of these is finding the right "hooks" in these pursuits that tend to be more obvious in competitive games. How do you "record your performance" when programming or holding meetings about business strategy? How do you review that recording after the fact? What criteria do you use to evaluate success and failure?
It's certainly not as easy to do this with "games" that lack a clear scope like startups, but I've found regularly reviewing your performance ("Did this meeting have a clear agenda before starting?") and building checklists for what practices lead to success is immensely helpful.
Most of my programs are for ETL, error-scanning, packaging up some manual tasks, and so on. I am in the long tail of dark matter developers. I do not have DevOps because it makes no sense to have DevOps where I am. I am solo, there's nobody else to code review with, and so I chug along like I have for the past forty years -- "yeah, that function looks like crap, I can fix that."
There's a lot of people like me out there. We solve problems. We pick up a program we wrote ten years ago to make sure it is still usable before running it. We do not "deploy."
I think we need some new vocabulary about the business of programming, because this narrow focus sounds like it ought to include the guy who makes a custom mortgage calculator for the local credit union in Visual Basic, but it really isn't about him or what he does, and it might not be bad to remember that he and I are out there, chugging away.
Get this Gen X snobby attitude out of software development. You're making it harder for the rest of us to hire developers we'd actually want to work with rather than snobby douchebags like yourself.
I'd be more interested in project size, business pressure, cost incentives etc to explain why software always grow to a direction that seems to hinge on the unmanageable.
For instance I agree and implement all he says, but let's take one example: we can love unit tests, and I never push something for review without many, but there are fundamental limits to them: you can assert wrong in many ways without any kind of measure beyond coverage, you can make the same mistakes in the tests as you did in the implementation because you just misunderstood the business, you can rush a solution to solve a problem happening yesterday, and test half of the problem etc.
So doing unit tests ONLY won't save you either.
My 2 cent would be to make us users of the software, that would really help move towards stuff we stuffer tenfold the limitations and failures of. Adding unit test in the process is the absolute minimum (so I agree amateurs only should dislike them), but still just the minimum to get anything serious out. The maximum is to make us the clients, or them the programmers. A direction we discuss in investment banking where we fire traders to replace them with people who can launch profilers during automated trading.
Inevitably this has 100% to do with the culture of the work environment. Either those things are mandatory, enforced by both peers and management, or they’re optional.
This reads like a rant about a low discipline organization, where it’s impossible to change the culture, and thus easier to crap on those who don’t know any better.
"engaged in a specified activity as one's main paid occupation rather than as a pastime".
I wouldn't call fixing azure pipelines without any professional debugging tools a pastime activity.
Although I've met unprofessional people at work. Being a professional doesn't mean you're an expert.
Though I am a TDD fan I understand your point.
Yes and no. At $WORK we started using a security scanner and I'm triaging the issues. It's definitely a box ticking thing. OTOH I'm finding real, concerning issues.
Project I work at right now could really benefit from basic TDD principles, mainly just setting test / outcome matrices and basing production off of that (which logically follows into TDD). The requirements are largely set up front, yet we still shoehorn unit tests in after production is done, wasting both development and test time. Requirements rarely change in major ways, and they are often established months up front.
Other times I work on stuff where fundamentals change rapidly. At that point I'm spending 1.5x-2.5x the time just to include test I'm likely to remove, and TDD largely inflates time required I don't have or wish to spend. Often testing trivial things, too.
Though I am not very keen on the underlying reasons the author gives. Seem to be anecdotal and not cover a host of other situations the solution could cover. I think there can be many other reasons. Cultural for one.
In the example of the professional team they may still be beholden to write cheap code because of certain business decisions, despite tests and the fanciest of ci builds. Additionally ‘amateur’ teams could still produce high functioning websites if there goals were shifted toward leaning and measurements taken against customer satisfaction and reduction of bugs over time.
I think that's wrong way to put it. I think the difference between pro and amateur might be, even if both dislike something, pro will understand he needs to do it properly anyway and why.
For example, I dislike writing unit tests. In many years there has not been a single time the unit test saved me from anything.
I tend to be very pedantic when writing code extremely careful when modifying code written by other people. I don't rely on tests to tell me I have messed something because I know these tests written by a person with lesser work ethics cannot be trusted. So before I modify anything I do thorough investigation to understand what I am modifying, what my modification can possibly cause and whether it is not a problem.
If unit tests were done correctly (ie. up to the standard that would let me trust them) then yes, they would be helpful. But it requires only a single developer on the project, even one that has already departed, and you can no longer just trust tests to catch a problem. Also I am yet to see well tested code -- one that documents and thoroughly proves all detectable aspects of unit contract.
So I understand I am paying the price for other people not making tests correctly but I still have to write them nonetheless. I hope you understand why I can BOTH dislike it and be professional about it, at the same time.
You've never even made a typo that a unit test has helped you spot? You've never, ever, had a unit test show you that one of the assumptions was wrong that you made about the behaviour of a piece of third party code?
That seems mighty unusual to me...
Do you not consider unit tests useful because they might help others understand and catch changes to the implicit contracts in your own code?
This is as silly as stating that you need to build at least couple skyscrapers that fall before one that can stand up and can be occupied.
It is not at all difficult. Instead of spending my entire career writing couple of lines of code and then running it, to see if it works (which is training at being perpetually newb at programming), I spent it learning to write longer and longer pieces of code that I understand exactly what they are going to do and that work on the first try.
I can work weeks writing thousands of lines of complex code and have very good chance that the effect will be working code that needs no corrections.
Do I make silly mistakes? Sure I do. But I then try to figure how it happened and how to make sure I don't make those kinds of blunders in the future.
I also try to design the modules in such a way that it is not possible to misuse them (well, at least requires malicious intent or gross incompetence).
You see, unit tests reward people who break a lot, not people who put a lot of effort into not breaking things. I prefer to focus my efforts into not breaking things in the first place.
I wish this was more popular: https://en.wikipedia.org/wiki/Personal_software_process
Unit tests show you that the code does what it’s supposed to. Without them you haven’t demonstrated that, just asserted it, nor have you left a system that can be picked up by others with a reasonable expectation that if something does break, it will be caught.
Unit tests became popular relatively recently. When I started development decades ago there was no talk of unit tests at all.
Do you want to suggest that people were unable to effectively write working software back then?
Just think about this.
Unit tests are just one way to help make it more likely the code works. It is neither the only way nor the best way.
Others might call it experienced.
> Do you want to suggest that people were unable to effectively write working software back then
People are still unable to effectively write working software. Unit tests are useful for catching problems, which are inevitable, early. They have grown in popularity over the last couple of decades precisely because of the prevalence and costs of preventable errors in the industry. I'm afraid I don't believe that simply by trying really hard you can eliminate said errors, nor do I believe the productivity trade-off would be worth it.
> Unit tests are just one way to help make it more likely the code works. It is neither the only way nor the best way.
Absolutely, they are part of a whole spectrum of techniques and are far from enough in isolation. I've never claimed they are the be-all and end all. They're a useful and essential part of a system of checks and validations, not the only thing you need to do. The clue's in the name, they test units.
On the first try? Yes, absolutely they weren't, and still aren't.
> Unit tests are just one way to help make it more likely the code works. It is neither the only way nor the best way.
Agreed.
Release crap that breaks too often? OK, you have taken too much of another team's resources, and will have to release less and/or check your work much more carefully.
Release something that might look low quality to an outsider, but that actually works perfectly well? Fine - no negative consequences if nothing bad happens.
Some years ago I've implemented a check to fail the PRs if the lines touched on that PR don't have code coverage (delta-coverage = 100%). We aligned internally with all the affected developers and went with it. We defined that the rule is that 100% of the code needs to be covered, but it doesn't mean that the rules can't have case-by-case exceptions. Whenever someone needs an exception the teams gets together and approve an exception. Sometimes it is a backlog to write the tests later, or some files that don't need unit tests altogether.
This may have worked for us because we are 5 years into this codebase and it keeps on growing, but for more small projects this may be more hassle than it is worth.
Honestly, after the first 6 months (not easy, not gonna lie) I felt better about the codebase, and I love the confidence of trying things and having unit tests all around. There were times where I submitted a PR and forgot altogether to write tests and this rule caught me.
I recommend it, but as with any software development practice, this is not a one-size-fits-all game.
In the game development, videogames are primarily tested by humans. Games are highly interactive pieces of software often running on a variety of hardware with complex agent-based simulations. Are all game developers "amateurs"? I don't think so.
Any idea on how they get the kernel to scale without kubernetes?
To my mind, the main issues in software development are complexity and imperfect knowledge. We've developed a lot of practices like unit tests and code reviews which help us defend ourselves, but, ultimately, for any non-trivial software it seems like a losing battle, or if not losing, then the progress is slow and difficult and tenuous. (like trench warfare).
Preventing bugs is something especially our materials and system interaction engineers are very aware of. You don't want a consumer product to fail in the field and cause damage or harm so that's goal #1.
* Write tests for almost all code. * Code review with peers. * Deploy frequently with roll-backs. * Reward each other when things go well. * Help each other when things go wrong.
This leads to high test coverage, good knowledge sharing, progressional changes, and a healthy work culture.
Many companies have very good processes in place and the above does not hold true for their employees. I was once at a company and was blown away with how well their code was structured, processes, etc I literally had no work to do (very rare).
While the rest of the list is valid the author could have stopped at the first item Standards and still have made his point.
Perhaps the most perfect example of that is why JSON won versus XML for data serialization. Many people will claim that it's because XML is bloated. After all this was the primary argument of JSON's inventor Douglas Crockford. They aren't wrong, but its not why JSON won.
JSON won because it's specification is tiny. When all the boilerplate is scrapped off the latest version is about 5 tiny pages of text any high school student can understand: https://tools.ietf.org/html/rfc8259
Compare that to XML:
* XML - https://www.w3.org/TR/xml/
* XML Schema - https://www.w3.org/TR/xmlschema11-1/
* XSL - https://www.w3.org/TR/xsl11/
Those are HUGE and they are written to conformance precision for implementation engineers. No high school student will ever read any of that for pleasure. I remember reading those when I first entered software development and absolutely everybody thought I was out of my mind and promptly discarded everything I said if they didn't already know it. I remember that being particularly frustrating because ever recommendation or proposal had to read like a pitch deck to a VC, but if I wanted to do that instead of engineering or product development I would be brand evangelism or merchandising.
XML for a data conveyance medium is extremely powerful, but in practice this is completely irrelevant. XML is a world unto itself in all of its capabilities and potential, but that doesn't matter if nobody is using it.
Most Americans, regardless of their actual educational attainment read at a 9th grade level (high school freshman). That applies to entry level software developers as well. Computer scientists and inventors are not the average of software developers. On one hand this is great, because I truly believe anybody can be a software developer and write really bad code. On the other hand this is horrible, because many people are code monkeys that write either bad code only or are fundamentally limited to a small subset of solutions limited by a small subset of tools.
>Amateur software developers dislike
- Standards
- Unit testing
- Design patterns/SOLID principles
- Learning and setting DevOps and ALM (They like using it)
- Fixing the build
- Code reviews
- Code Analysis/Solution checking
What a troll statement, no way do 80% of software developers dislike those things.. maybe.. 20%?
> - Standards
Resistance to using formatters and linters because they prevent you from merging code more quickly; "it's annoying". Two of the two-dozen devs on the product decide that they want to use NetBeans instead of Eclipse even though the formatter is built for the the latter and everybody else uses it so they can't format their code properly.
> - Unit testing
I recently went four years without writing a single unit test professionally. When I _did_ write unit tests I worked on one team where the only important metric was coverage percentage, not corner/edge cases or intentionally trying to break the software. People would write tests for auto-generated getters and setters in C#. That's right - they would _test the compiler_ just to satisfy a business metric.
> - Design patterns/SOLID principles
My tech lead at a previous job refactored a pretty substantial service I wrote with no team input to remove any semblance of organization or convention. The repositories, factories, and facades I built got merged into a giant single "helper" object just to follow some weird anti-pattern that they'd established. It wasn't testable, there was no separation of concerns, and it ended up being nigh-unreadable.
> - Learning and setting DevOps and ALM (They like using it)
> - Fixing the build
I've been the "CI guy" at almost every software job I've had because some people are afraid of the command line and lack an understanding of the build tooling outside of the three SCM operations they know through Tortoise and the play button in their IDE.
I could go on but you get my point. Software development is a vast industry and there are some pretty dark corners. For every high-performing team that has tech-savvy devs there are body shops full of people that are trained by rote to "build software". It's not pretty.
[1] https://tomgamon.com/posts/a-losers-game/
Both Ben in this "Software" and Tom Gamon in "Programming" anchor their arguments to Charles Ellis, & his example of tennis as a game where the talented score points, and amateurs inflict self harm.
Both of these articles espouse a similar, conservative minded viewpoint that maintaining & supporting is a more key or perhaps just more-absent activity than progressing. They warn that devotion to progressing/going out and winning often brings about doom & trouble. They speak to us of the hazards about, that the paths available to the software's future becomes confined or the ground unsteady if we don't take our software environment seriously.
I'm both very sympathetic to this software-conservatism , because (a) legacy systems/the past rule so much of the software world, and (b) we certainly do make confounded mistakes a lot, but also deeply worried about what it's done to our moral character. Software isn't eating the world anymore: it's past that now, that's past tense. Software has eaten the world. At almost everyone company you go to your world will almost entirely be already consumed by mounds of existing software, upon which the company is most often busy accreting new layers of software that will shortly settle into place & likewise become buried. It's a frank truth that minding your environment, trying to insure some safety & quality to the layers is critical, the belief that we should/ought/must build solid baseis extremely valuable here. But I somewhat fret programmers have been tamed into minding our own loser-dom, am concerned that we stop looking up to the stars, when we stop being brazenly brave. We have immense immense powers, and from so many camps- within the programmerhood & external- I see a reaction of panic, & fear, & distrust to potential. Which is both warranted, but also really quite besides the point, is too often too strong a diminishing force for great potentials programmers have such keen great sense for.
I feel there is an over-regulation, an over-pressuing on our social systems these days. "Overnight Pizza and the Consistent Unreliability of Expert Guidelines"[2][3] is recent article ostensibly about Expert Opinions & the low-information-density environments such guidelines are crafted in & for, but it's also an incredible story about social pressure, the urge to be right, about the emotional high one gets from being certainly completely correct & proper & everyone else being a fool. It's about overly absolutist perspectives, that don't allow for a bigger continuum of opinions. And I think a lot of software folk have turned in to the "overnight pizza will kill you" camp: they have encountered some parts of the maelstrom, tasted what the uncivilized is like, and their reaction is to build & fortify against the encroaching dark, to turtle up, & build strong best practices & robust processes. Which is both noble, respectable, given the maelstrom of software, but also... I feel like our lack of adventurous spirit often holds us to petty tasks, and keeps us from exploring & seeking better lands, with much richer yields.
[2] https://residentcontrarian.substack.com/p/overnight-pizza-an...
[3] https://news.ycombinator.com/item?id=26635856
Programmers, the New Kingmakers[4], are also in an enormous tension. Business's often proclaim that they want go-getter attitude, that they folks focused on landing wins, making sure their every effort helps the customer. But often programmers are very very alone in seeing a bigger picture, seeing long term costs, seeing how the business is creating amateur grade software that will not hold up. Programmers can feel under strain to deliver, and conservatism naturally results, a concern that things will fall apart, that core formative activities won't have time to occur or mature, that the result will be disorder. Few companies internalize & earnestly grapple with an understanding of how the sausage is made, programmers often view other people as viewing them as resources, to be used, tapped, often without awareness or responsible handling, without understanding that the magic has a price, that it's stacking up. Those closest to the craft have a deeper insight into how the business's "win orientation" is creating (& compounding) amateur losses, and they feel enormous protectivity: that they must claw from the business the good acts it cannot see and that it needs.
[4] https://thenewkingmakers.com/
But that's not the worst part of the business environment to me. The worst to me is writ large in "Why software engineers should be CEOs"[5]. We are incredibly creative, we see enormous potential at every step. Only rarely does the business let us drive towards the true fantastic excellences that we dream of pursuing. Just as the business doesn't understand the loser's game challenges that are all over the place, oh, sad, the business also does not have anywhere near the vision or creativity of the individual, of the coder, who sees possibility & value oozing out of so many areas, often so untapped. And programmers are not put into decision making roles nearly enough, not given structure & the attitude that they can strike, that they can chase down big game, game the rest of the company often has a hard time seeing. The socialization processes that work places must go through to allow commitment are very high, and so programmers simply do not have the time, ability, or often even the common language to get the businesses play the winning game. We must trust that the business somehow is aligned to let us make them kings, rather than taking an active stake in pushing the business towards their would be kingdomship.
[5] https://www.tlt21.com/why-software-engineers-should-become-c...
Beware committing your life to mastering the losers game!! You are the dreamer of dreams. It hurts, it's always a challenge, but please, dear fellow programmer, stay in touch with your noble (& a little bit wilder) selves. I believe in you.
> Software engineering has its own political axis, ranging from conservative to liberal.
Which is really very much at the heart of what this whole winners vs losers game discussion is about, I think.
>Only rarely does the business let us drive towards the true fantastic excellences that we dream of pursuing. Just as the business doesn't understand the loser's game challenges that are all over the place, oh, sad, the business also does not have anywhere near the vision or creativity of the individual, of the coder, who sees possibility & value oozing out of so many areas, often so untapped. And programmers are not put into decision making roles nearly enough, not given structure & the attitude that they can strike, that they can chase down big game, game the rest of the company often has a hard time seeing. The socialization processes that work places must go through to allow commitment are very high, and so programmers simply do not have the time, ability, or often even the common language to get the businesses play the winning game. We must trust that the business somehow is aligned to let us make them kings, rather than taking an active stake in pushing the business towards their would be kingdomship.
The socializing aspect is spot on but there is also a fear that the business people have of losing control. On the software domain they are clueless and they prefer to keep the reigns, even if their decisions are bad than cede some power to software people. They are afraid that software people would become to powerful.
The game is also about good co-operation, helping colleagues succeed without imposing dogmatic requirements, and making friends with influential people connected to the software development team.
This is rather an article about loosing the “game”.