Why I hate the word “Pragmatic” and other rants
I told myself that when I started my new blog that I’d try not to rant as much as I did in the CodeBetter days, but oh well, here we go anyway:
Software is a young profession and judging from the rate of change and improvement over my 16 years as a software developer, we’re still learning a lot of new lessons — or relearning old lessons for ourselves that some other group of developers already learned years ago. The great part about that ever changing landscape is that constantly learning new tools and techniques is so much more fun than my first job as an engineer where I mostly certified piping system designs with the “boiler code” that dated back to the 1800’s. The downside is that I think that developers as a whole are terrifyingly bad at sharing information and debating or reasoning about the merits of various alternatives — especially if we feel threatened by other developers promoting tools or techniques that we don’t yet know or use.
I want to ban these words and phrases from technical discussions
I’m betting that many of you are familiar with Godwin’s Law:
“As an online discussion grows longer, the probability of a comparison involving Nazis or Hitler approaches 1.”
From my perspective, the importance of Godwin’s Law in practice is that conversations effectively lose all usefulness when highly charged words and hyperbolic comparisons start getting tossed around. Much like George Carlin’s Seven Dirty Words, I’d like to create a new list of words and phrases that should be banned in technical conversations at least until we learn to use them a little more wisely:
- Pragmatic — If you follow me on Twitter you surely know that I despise the word pragmatic as it’s usually wielded as a magical talisman by inarticulate developers the world over to win debates and justify whatever random decision they’ve made to other developers. More on this in the next section.
- Fetish — As in “I don’t get your fetish for static/dynamic typed languages.” What you’re doing is shutting your mind off to the merits of different ideas than you’re own.
- Zealot — see the above.
- Dogmatic — Dogmatic is generally used as a pejorative term, but sometimes it’s not. Some techniques are most effective when they’re applied consistently. Again, I think developers mostly use this word to denigrate or delegitimize the differing opinions of other developers.
- Academic — Denigrating some technique as being more theory than something that’s practical to use. You might be right and my experience in a couple different fields is that there is some real distance between theory and reality, but using the word “academic” to describe a technique you don’t use is a sign of a closed mind. Sample usage: “OWIN is a kernel of a good idea wrapped in a lot of academic masturbation.” I’m admittedly guilty of using this quite frequently in reference to enthusiastic proponents of functional programming.
- “Why don’t/didn’t you just” — I’m bad about using this on other developers. Sample usage: “instead of unraveling the Gordian Knot painstakingly by hand, why didn’t you just cut through it with the sword laying over there that no one told you about?.” The cruel reality of software development is that frequently the simplest solution involving the least work is not the obvious solution.
- “It’s obvious” — My ex-wife absolutely hated it when her professors in college used the phrase “it should be obvious to the most casual observer” when their point wasn’t clear at all. It’s just a way of either putting down your co-workers or using loaded language to win an argument. Contributed by my colleague Matt Smith.
- “Git r’ Done” — Used non-ironically it’s just a cutesy synonym for “being pragmatic.” I should probably ban “git ‘r done” because in my circles it’s code for bad developers that don’t care about any kind of quality as long as the immediate work gets done sorta, kinda on time and mostly “works.”
- “Use the right tool for the job” — This is an empty calories kind of statement and a cliche. I usually interpret this as “I just want to be left alone to use what I already know and I’m not interested in continuing this conversation”
- “We just have to get this out the door” — I think there’s a real tension and a necessary balance between making decisions tactically for immediate problems and thinking strategically for the long term. While being an architect astronaut is a sign that you’re too far into the strategic side of things, using the phrase “we just have to get this out the door” is often an indication that your team might be veering way too far in favor of short sighted tactical decisions while missing opportunities to improve their productivity by making changes in process, tools, or a redesign of a bad subsystem. My fear — and my experience backs this up — is that teams that use this phrase and moreover believe it, have shut off their minds and just started to bang harder and faster on their keyboard. My favorite analogy for this is always the saying “I’m too busy chopping trees to stop and sharpen my axe!“
- Shiny Object — I’m guilty of this one. As in, “you just want to use XYZ because it’s the new shiny object”
- Cargo Cult — All the analogies to cargo cults and teams just going through the motions of doing Agile development were kind of funny a couple years ago, but I think the term “cargo cult” is over used mostly as a way to put down other people at this point. If you’ve been living under a rock and haven’t heard this term, I liked James Shore’s Cargo Cult Agile from back in the day.
If you use any of these words and phrases to another developer, you might have wasted a chance to learn or teach something new.
Good Decision Making, Modeling, and being Pragmatic
Taking the definition from Merriam Webster, being pragmatic is:
dealing with the problems that exist in a specific situation in a reasonable and logical way instead of depending on ideas and theories
I think that developers often conflate being pragmatic with doing things well. Being reasonable and logical sounds like a great way to be successful, but you can be pragmatic until the cows come home and still make bad decisions all day long if you’re using bad information or not accounting for other factors. Making good decisions isn’t so much about being pragmatic, dogmatic or zealous so much as it is about constructing the right mental model that represents more of the important factors that go into the decision.
As I alluded to earlier, my educational and early professional background is engineering. My primary job was often about creating models to accurately simulate the real world in order to validate decisions or optimize designs. Needless to say, the better and more accurate your models are, the better your real results.
I thoroughly enjoyed a special projects class I took my last year of school where we designed thermodynamic systems based on optimizing either cost or capacity. To do the optimization, you had to model the various factors (length of a connecting pipe, depreciation, rate of heat loss, etc.) with equations that could be solved with optimization software to find local minimums or maximums.
Since it’s just math, two teams working on the same project should always arrive at the same designs and decisions, right? Right?
What we found in the course of doing these projects was (unsurprisingly) that:
- The calculated optimal design could be much different if you added or ignored certain factors. Maybe my team accounted for the pressure drop across a mile of pipeline while the other team assumed that it was constant. Maybe the other team made different assumptions than we did.
- The calculated optimal design could also be much different for shorter timeframes than it was for longer timeframes.
To make this concrete in terms of software development, take the decision about whether or not to write unit tests for any given piece of code:
- Writing the extra code to automate unit tests takes more time than just writing the production code. A big point against the unit tests.
- Only end to end or integration tests would be able to definitively determine problems in the code in question. Don’t write the unit test.
- An end to end test would be very expensive to write. Write unit tests for what you can easily unit test.
- Writing automated unit tests might force changes to the way you structure your code — which might be a forcing function in favor of better factored code which is good or additional complexity that you don’t want
- Without unit tests you might not catch problems until later when the problem will be harder to find and fix. A point in favor of unit tests.
- Using a debugger is an inefficient way to solve problems in code and foregoing unit testing increases the risk of long debugging sessions. Writing automated unit tests frequently reduces the amount of time spent using a debugger.
- Automated tests of any kind definitely save time in regression tests. A point in favor of writing the tests in the longer term.
- The existence of automated tests can lead to better reversibility so that you can make changes safely later. A point that might be very important or not at all.
If you base your decision about whether or not to write unit tests on only one of these bullet points and not a combination of many or all of them, your decision making isn’t as likely to optimal in the end. Also, your decision making should probably come to different results on a one week project versus a multi-year project.
Again, making better decisions isn’t just about being “pragmatic,” it’s about creating a mental model that more completely and accurately accounts for the positives and negatives of any given decision and also being cognizant of the timeframe in which you need to optimize. If you make the decision about whether or not Making decisions pragmatically but with incomplete information or understanding of your problem is still bad.
Going back to the point about being too focused on making incremental deadlines and being too focused on the tactical, I’ve far too frequently seen teams forgo solving some sort of technical debt issue that is slowing them down because they had to make their next iteration. In the very short term, they might be right — but if the time saved over X number of iterations is greater than the time it takes to solve and fix the technical debt issue then you need to stop and fix that damn technical debt problem.
To make that last paragraph more concrete with a real life example from my shop, let’s say that your team is working with a system where each and every new vertical feature requires changes to code in six different git repositories. Would you continue to pound away on new features to maintain your current velocity, or stop for a little bit to combine all the repositories into a single logical repository where it’s much easier to make changes in one place and very likely increase your velocity afterward?
I asked my Twitter followers for more examples of words and phrases we should ban and a large number of replies contained the word “just.” As in the time a business analyst told me that if we were to use our brand new website application as the front end for a system built by another branch of our company that neither of us had other seen it would “just be some refactoring.” Using the word “just” is a perfect example of Lullaby Language that we should probably avoid using because it gives us and our listeners a potentially false sense of security.
Another loaded word is “should,” as in “the new build should work” with an unspoken admission that they hadn’t tested the exact scenario in question. I had a very enjoyable co-worker years ago that would react comically to statements like that with “you said ‘should!'” (for my current colleagues, this is the guy that got me started on the finger on the nose gesture you’ve all seen by now).
Other examples from the peanut gallery were:
- “should be a quick fix/change” — putting pressure on you to turn it around quickly with no real forethought about how big it really is
- “this is too simple/small for testing/versioning” — famous last words…
- “The deadline is already set. Can we make it?” — I really enjoyed Jez Humble’s talk at NDC London last year about how we should concentrate more on delivering value instead of just trying to hit deadlines
Non Technical Folks and Estimation
I got a lot of other complaints on Twitter that mostly boiled down to project managers and other non-technical folks setting deadlines, time limits, or estimates for developers. I’m a big believer in the idea that developers should do most of the estimation work — and even then, those estimates should be treated as unproven working theories. The only time I think a project manager can get away with doing estimation is when there’s plenty of historical data for the project on similar stories and the composition of the team is stable.
Like many developers in Austin of my generation, I started my development career at a large captive IT shop that was famous for generating truly awesome horror stories. The very last thing I did there was to help kick off a new project to replace an existing web application that our business wasn’t happy with and we felt would be easier to rewrite than improve (it build dynamic HTML inside of VB6 COM objects hosted in ASP classic). Since that very year I had had my bonus slashed because of how far off my estimate was for a previous project, I was appropriately paranoid about getting it right this time around. To that end, I spent a lot of time using use case points (this was so long ago that RUP was still cool) to both define the scope and a first estimate. Because I’ve told this story so many times, I still remember the basic details of the proposed system:
- A small new database schema to be what we’d now call the read side model — maybe 2 primary master/detail tables plus the normal contingent of lookup data tables
- A pretty complicated web screen with a lot of different user interactions, and this was way before things like jQuery or Angular.js
- About a dozen integration points to legacy systems that we had had trouble with in previous projects
When we finally got a project manager I tried to present my use case’s and estimates to the new project manager but I was basically told “don’t worry about it hon, I’ll make the project schedule.”
The next day I got the email with the new Excel schedule attached. As memory serves me, it was an old fashioned waterfall schedule that roughly went:
- 40 days for logical database design
- 20 days for physical database design
- 10 days for the integration work
- 10 days for the web application
I was apoplectic because it was pretty well exactly opposite of what I came up with in every way and pushed all the technical risk to the very end of the project — but I quit the very next week anyway so it was okay;) The PM wasn’t amused when I drew two boxes and one line on her whiteboard and said “there, the logical database design is done!”