In my specific case, TDD; and unit testing as religion in general. I am sure others can make similar arguments against the other two in the types of work they do. My point here is that every project is different, and that projects that do not use one or any of these techniques are not inherently buggy.
I believe strongly in manual testing and automated integration testing for the type of work I do (when executed by an experienced QA); but I have not seen unit testing save anywhere near the time or effort it requires. I am sure there are types of projects for which unit testing solves more problems than it creates, but I have not worked on that sort of project. In my experience, unit testing stops the type of bugs you wouldn't have had anyway, and doesn't do much to mitigate integration bugs (which are the vast majority of bugs I've seen). I've also seen TDD make developers overly myopic. Passing tests do however make for a conveniently reassuring metric to give to business leaders who don't care to understand what they mean or how software is built.
He/she is not narrowing to a specific type of programmer, or a specific type of programming. I am explaining why I "don't care about correctness".
Forgive me if this article is meant to be read in an academic context; I am not an academic.
I don't have time for distracting meta-work with questionable efficacy. My prime requisite is to deliver actual value, not dubious internal metrics.
One of our jobs as programmers, leads, or architects is to determine, of many strategies to solve a problem, which are (or may be) appropriate for the current context. Testing is done the same way; and parameters for testing are decided by the QA department. Any strategy that claims to be universally applicable (like anything labelled "clean" or "correct" or "best practices") is likely at least partially bullshit. Every problem is different, and every requirement requires special care to ensure what's being done is appropriate for achieving both long and short term goals within time allotted.
It's a given that the business already pushes as hard as they can on deadlines. If I have to cut effective quality assurance, or make compromises on what will and won't be done a maintainable or performance oriented manner to fit in meta-work that really doesn't matter; I'm going to pick a fight.
The development team has a finite bullshit budget, and the business has generally spent our bullshit budget before we get to your correctness bullshit.
The very notion of universal "software correctness" within a system of sufficient complexity is reductive and borderline offensive.
x86 and it's ancestors eating the markets of [iAPX 432, Itanium, i860, i960] has taught a lesson in the value of an install-base in the server and desktop market. Let's see if history repeats itself?
Apple has never seemed to really be into the concept of backward compatibility; but historically the rest of the industry has been.
The web is, at it's heart, a distributed document system with a layer of hacks on top for building applications.
You can create pure documents for the web without any code. Documents are, by nature, easily expressed declaratively; and it's not impossible to build an intuitive interface to express declarative data visually (or hide the data aspect completely in the case of a WYSIWYG interface).
Modern web pages are, in my mind, a sort of document/application hybrid (with few exceptions as of 2020). We have yet to find a better way to express an application than through textual code.
Procedural code is branching and time sequenced; how do you express that in a meaningful way visually? For some reason our imaginations find it easy to understand that the side effects of every line before this one are still around, and we're pretty good at picking up the concept of branching and jumping around the instructions; but I believe that's because the code is essentially a sequenced list of commands (and our brains are good with sequenced lists).
The attempts I've seen at visual programming remove common programming capabilities to fit more neatly within their visual medium; as long as that is the case, I don't see visual programming breaking out of being used strictly in DSLs (domain specific languages), which are often inherently limited.
I don't think a no code future is likely, as long as custom software is in demand; however I can see a future where fewer technician type roles require code. Of course that would require someone to spend a lot of money building a standard visual vocabulary of related tasks, excellent ergonomic interfaces, and extensible GUI systems; the type of things the FOSS world hasn't built much of a community for as far as I am aware.
Are you disillusioned with technology, or with the business of technology?
In my experience, the term "business" is short for "the business of exploitation". Exploitation is ugly, and I've had experiences that can be compared to yours.
Our occupation (if you're doing it right - and few are) is masochistic in nature. You suffer to grow, and you grow to suffer (sometimes quite a bit more) for greater pursuits next time. It's the definition of type 2+ fun (https://www.tetongravity.com/story/adventure/the-three-and-a...). If you did the type of things I do, it would be easy to see our primary job as the application of self-discipline to mitigate emotional and existential pain caused by consistently pushing your limits (past your fatigue plateau); and the creation of new solutions are side effects of the mental blender you are capable of holding yourself in for 8+ hours a day. If you've had family members beg you to quit jobs "for your health", you probably know what I'm talking about.
Knowing (as I do now) how the business works can change the context behind the work. Context can be the difference between being a hero, and being exploited. I like being a hero; I don't like being a victim. I will happily sacrifice of myself to make something that users will love, or something that will change the way things are done; I don't want to bleed to make some dickhead rich.
If you have the money to coast for a while, perhaps it's time to think about building a non-profit. A non-profit would be less likely to attract those looking to exploit. Boil what you want to do down to chunks that you can complete yourself, and make sure it's something you're willing to bleed for.
Business logic is certainly a reflection of a programmer's understanding of the business, as well as their skill in applying object oriented concepts (or whatever) and occam's razor to express it in a manner that doesn't balloon in complexity and isn't cognitively wasteful. There's an art component, and a science component; and if they're both right it will make a solid foundation for everything else, and for communication with the business.
I am not aware of a standard (and in depth) definition of what a software architect is; other than it being the next step after team lead, and the last step before pure management (unless your company offers a research track - which nearly no one does). The interpretations I've run into are pretty varied. My way is certainly not the only way, and my way is an amalgamation of aspects of others that I admired.
For reference, I'm 36, have been programming professionally for 20 years, and have been an architect for 10. I seek out difficult projects.
Here are some (likely idealized) descriptions of my favorite past architects:
"Never say no"
My first architect took immense pride that at 40 something, he had never had to say no to a product manager. We were going to build whatever the business wanted, with no push-back (only what he called lateral guidance, or "yes, and"). The business would arrive with specifications, and he'd treat them as if they were rough drafts; "OK, let's get to work". He'd disappear into meeting with the business, and emerge days later with a nearly completely rewritten specification (which he had written himself and was usually more feature rich than the original), and everyone was happy. He explained to me after a few years that most bugs and development problems come from the blind-spot the business has for how software works, and the blind-spot development has for the business. A specification with no blind-spots is much easier to turn into software. Every project I worked with him on went smooth, and was delivered on time. I strait up stole and expanded his technique as the foundation of my architecture philosophy.
"Make me one"
I worked with an architect that insisted everything be built in-house (no unnecessary external dependencies). He'd look at the features of some other framework or tool, copy the bits he liked out of their documentation (as if they were requirements), and turn to us and say "now we're going to build our own". I loved this guy, he pushed me so far outside of my comfort zone that every day was a frantic adventure. "Write me a sketch; you have 4 hours". He didn't like whiteboards, he liked code and rapid iteration. He was brutally honest and ripped my code apart at least twice a day. We'd play code tennis for a couple of days, then a polish phase before QA. I was in hyper-focus for 8 hours every work day, and the practice at rapidly building (and rebuilding and rebuilding) all sorts of difficult components (that all made it to production) made me fearless. I lost that job to the 2008 bubble burst, but the year I spent there easily advanced my skill set by 5 years.
"If it's not fast it's useless."
I worked with an architect who came from systems programming. He had an incredible resume. He spent a lot of time refactoring for performance. If he liked you, he'd explain what he did to your code and why; if not, that code became his now. He spent a lot of his time in instrumentation, testing this solution against that solution for execution time and memory usage, merging the best bits, and testing against a different approach. His favorite phrase was "prove it" (and I spent a lot of down time trying to prove things to him through examples and instrumentation). I learned a ton in an effort not to disappoint him. It was no longer enough to know how to do something; I had to know many ways to do it, and which performed better in what scenario. "What, as an individual programmer, do you bring to the table if not performance? If your solution doesn't perform, you let everyone else down." He dramatically and permanently changed the way I code and the way I design applications.
"If it's not predictable I hate it."
I worked with an architect who's main focus was the application as it ran in production. He spent a significant amount of his time combing through debug logs and recreating log messages locally to understand what's going on, tracking down run-time issues that customers called in with, building instrumentation and internal tools, looking at characteristics of the application as it ran with network operations, and treating the production application as a living thing. I learned a ton from him; he changed the way I look at applications.
I've also worked with a number of architects who I did not like, and who I learned nothing from. Among them:
- The guy that misinterpreted the book Clean Code and turned the code-base into a ridiculous mess
- The guy who made decisions like we were Google, when we most certainly were not
- The "lead by Lint" guy
- The design by committee guy
- The "non technical" architect
- The "I rebuild most of the application last night" guy who just made it worse
- The "I read it in a blog so it must be both true and universal" guy
I am a senior software architect. My job is to balance performance against complexity.
If my system is slow, it's my fault.
If debugging or expanding the system is too difficult, it's my fault.
If someone wants to know how the system or business works in depth, I am the one that they should come to.
I spend the majority of my time chasing down, enforcing, and simplifying the universal theory of our business (the core of our software solution).
The universal theory of our business is a living collection of concepts, designed to accurately model non-virtual concerns in virtual space. If there are too many edge cases, it is a sign that the universal theory is inaccurate, or not robust enough in some areas. If there are too many bugs, it is a sign that the universal theory has not been communicated or enforced well enough, is inaccurate, or is too complex in some areas. As our business grows, or our understanding of the business expands, the universal theory will change; at times dramatically. Malleability (the ability to adapt our software to these changes effectively and efficiently) is one of my top two concerns; the other is latency (how long it takes for any one request to get a complete response).
The theory shrinks and becomes better documented as it evolves; the goal is to move from describing behaviors as correlation to describing them as accurate causation. To fill in the blanks.
I should mention here that this does not mean every line of code in my projects is easy to understand. Writing a fast system of high complexity requires at least some components that are written exclusively for the computer's benefit (that is, highly optimized and inherently difficult to read). These components should be written with clear documentation, clearly defined public members, written discussions of why it works the way it does (and common ways to accidentally break it), redundant ownership, and regular auditing to ensure code rot is avoided.
I have yet to meet another architect that sees their job the way I see mine.
If the system you're working on defies complete understanding, you can probably blame your architect.
If I see your name again in a list of resumes someday, I'll put yours on the top.
- 21 year R&D greybeard (37 years old)