Against Best Practices
The author critiques the concept of "best practices" in programming, arguing they can be harmful and overly rigid, advocating for a more nuanced and critical approach instead of blind adherence.
Read original articleThe article discusses the author's skepticism towards the concept of "best practices" in programming, arguing that they can often do more harm than good. The author suggests that these practices are frequently promoted by individuals who misuse them as arguments from authority, or by inexperienced programmers who fail to assess their relevance. While acknowledging that some best practices can be beneficial, the author emphasizes that many are merely opinions and should not be applied universally. The critique extends to specific examples, such as Postel's law, the absolute rejection of global variables, and the strict adherence to principles like DRY (Don't Repeat Yourself) and SOLID. The author argues that such rigid applications can lead to unnecessary complexity and hinder practical problem-solving. The discussion also touches on the challenges of debating best practices, likening it to a "gaslighting effect" where questioning these norms can lead to accusations of negligence. Ultimately, the author calls for a more nuanced approach to programming practices, advocating for critical engagement rather than blind adherence.
- The author believes "best practices" can be harmful when applied uncritically.
- Many best practices are seen as opinions rather than universal truths.
- Rigid adherence to principles can complicate programming unnecessarily.
- The article critiques specific practices like Postel's law and the absolute rejection of global variables.
- Debating best practices can lead to accusations of negligence or carelessness.
Related
Holding a Program in One's Head (2007)
The article highlights the cognitive processes in programming, emphasizing mental retention of code, the impact of distractions, and advocating for smaller teams and independent work to enhance creativity and understanding.
The Open Source Project Maintainer's Guide
The article humorously critiques ineffective open source project practices, suggesting counterproductive methods like using uncommon version control systems, ignoring bug reports, and prioritizing features over fixes, while advocating for better management.
Software development topics I've changed my mind on after 6 years in industry
The author reflects on their software development views, emphasizing typed languages for diverse teams, the importance of architecture, context-dependent best practices, and questioning the necessity of many project managers.
The Rise of Worse Is Better
The text contrasts two software design philosophies: the MIT approach, which values simplicity and correctness, and the worse-is-better philosophy, which prioritizes implementation simplicity, suggesting a need for reevaluation in the Lisp community.
Build systems, not heroes
The article highlights the need for system-based approaches in enterprise programming to reduce risks from personnel changes, ensure consistent quality, and improve workflows, despite potential resistance from individuals.
- Many commenters agree that context is crucial when applying best practices, emphasizing that what works for one situation may not work for another.
- There is a consensus that blindly following best practices can lead to poor outcomes, and that understanding the underlying reasons for practices is essential.
- Some commenters express frustration with the misuse of best practices by inexperienced or dogmatic individuals, suggesting that this can lead to a culture of rigidity.
- Several participants highlight the need for balance, advocating for the use of best practices as guidelines rather than strict rules.
- There is a call for better communication and documentation of the rationale behind deviating from best practices to foster understanding among team members.
https://respectfulleadership.substack.com/p/dan-morena-is-a-...
My summary of his idea:
No army has ever conquered a country. An army conquers this muddy ditch over here, that open wheat field over there and then the adjoining farm buildings. It conquers that copse of lush oak trees next to the large outcropping of granite rocks. An army seizes that grassy hill top, it digs in on the west side of this particular fast flowing river, it gains control over the 12 story gray and red brick downtown office building, fighting room to room. If you are watching from a great distance, you might think that an army has conquered a country, but if you listen to the people who are involved in the struggle, then you are aware how much "a country" is an abstraction. The real work is made up of specifics: buildings, roads, trees, ditches, rivers, bushes, rocks, fields, houses. When a person talks in abstractions, it only shows how little they know. The people who have meaningful information talk about specifics.
Likewise, no one builds a startup. Instead, you build your startup, and your startup is completely unique, and possesses features that no other startup will ever have. Your success will depend on adapting to those attributes that make it unique.
If you take it as a given that some number of people are going to get an idea lodged in their head, treat it like gospel, and beat as many other people in the head with it as they can... the best strategy you can adopt is to have the ideas in their head be at least somewhat useful.
Yes, reasonable people understand that "best practices" come with all sorts of context and caveats that need to be taken into account. But you won't always be dealing with reasonable people, and if you're dealing with an asshole, zealot, or idiot, I'd sure as hell prefer one who blindly believes in, say, test-first development versus believing that "test code isn't real code, you should spend all of your time writing code that ships to users" or some other even worse nonsense.
The author seems to be arguing for nuance: that these “laws,” require context and shouldn’t be applied blindly. I agree.
However they shouldn’t be rejected out of hand either and people recommending them aren’t idiots.
Update: one problem with “best practices,” that I think the article might have unwittingly implied is that most software developers aren’t aware of SWEBOK and are repeating maxims and aphorisms they heard from others. Software development is often powered by folklore and hand waving.
The author might go on to make other points that are worth discussing, but lays out his supporting arguments clearly in the opening paragraph. Best practices do not necessarily do harm because they offer bad advice, they do harm because they are advocated for by zealots and the inexperienced.
My first reaction is how unfortunate it is that this particular developer has found himself in the presence of bad engineers and the inexperienced.
But then, the argument is automatically self-defeating. Why is the rest of the article even worth reading, if he states upfront what his arguments are and those arguments are very easy to refute?
It is deeply irrational to judge the merits of an idea based solely on who is advocating for that idea.
My advice to the author is to reflect on the types of positions that he accepts, the ones that have him so put off by the people that he works with that he is openly writing about abandoning what he admits could be sound engineering practice, solely based on who that advice is coming from and how it is being delivered.
Developing software is complicated. It is constant problem solving. When solutions to problems come about, and we abstract those solutions, it is quite easy for individuals to misapply the abstraction to an inappropriate concrete. To drop context and try to retrofit a lousy solution because that solution was appropriate to a slightly different problem. But at the end of the day, these abstractions exist to try and simplify the process. Any time you see a "best practice" or design pattern acting as a complicating force, it is not doing its job. At that point you can either be objective and exercise some professional curiosity in order to try and understand why the solution adopted is inappropriate ... or you can take the lazy way out and just assume that "best practices" are the opinions of zealots and the inexperienced who blindly follow because they don't know any better.
The problem is that a lot of true things in the world are counter-intuitive. So insisting that all the rules "make sense" in an immediate way is clearly a non-starter. In the safety industry there are many examples of best practices that are bred from experience but end up being counter-intuitive to some. For instance, it might not make intuitive sense that a pilot who has gone through a take-off procedure thousands of times needs a checklist to remember all the steps, but we know that it actually helps.
It's hard because there is usually some information loss in summarisation, but we also have limited memory, so we can't really expect people to remember every case study that led to the distilled advice.
As a chemical engineer by training, though, I have constantly been amazed at how resistant software people are to the idea that their industry could benefit from the kind of standardisation that has improved my industry so much.
For example I think that strict formatting is a good thing. Since I tried to use Prettier I'm using it and similar tools everywhere and I like it. I can't do vertical alignment anymore, it eats empty lines sometimes, but that's a good compromise.
May be there should be a good compromise when it comes to "best practices"? Like "DRY" is not always best, but it's always good enough, so extract common stuff every time, even if you feel it's not worth it.
I often deal with this dilemma when writing Java with default Idea inspections. They highlight duplicated code and now I need to either disable this inspection in some way or extract the chunk of code that I don't really think should be extracted, but I just can do it and move on...
- small localized team vs big distributed team
- bug fixes and incremental improvements vs green field poc
- saas vs system scripts
Context matters, and if people aren't giving you the context in which they deem practices to be "best", they are myopically wrong
> “Don’t Repeat Yourself” (DRY) is basically good advice, but sometimes just copy/pasting things is just the more pragmatic thing to do, and not really a big deal.
Duplicating code on purpose is not about being pragmatic, it's about recognizing when DRY would violate the single responsibility principle.
The ability to weigh tradeoffs in context is what makes some engineers better than others.
It annoys me to no end when devs talk about some specific technical change "increasing accessibility". The accessibility best practices are used as a checklist where more checks = more accessibility points = better. It results in people gaming the score with meaningless repetitive metadata or low-impact tweaks, rather than actually improving the descriptive/alternative/touch/visual interface. Usually never even trying any alternative method of interacting with an interface.
The best practice is "always include metadata", but it leaves off "... that adds context about the element rather than noise, and integrates with a surrounding application that uses consistent metadata labelling. Remember, this is a portion of a complete descriptive interface someone has to use."
These best practices being driven into people's brains verbatim means conversations devolve into inane on-or-off taxonomy discussions like "is this colour accessible?" or "have we added accessibility? Do you need a ticket for that?" where pushing back isn't seen as caring about users, it's seen as being "against accessibility".
https://graypegg.com/2023/11/25/the-private-definition-of-ac...
Prospects and customers desperately want to know our "best practices" and then complain when we say "it depends" or something experimentation is required, as if we are hiding secret teachings from them.
For me this is more a personality test: people who just want solutions on a silver platter vs DIYers who want to tinker and distrust black boxes.
1. Advice which worked in one situation - “we tried Agile, everyone should use it!”
2. Proven stuff like code review, which you call best practices when begging your org to implement it: “please let’s do it, I can clearly see how this will improve our org.”
These 2 examples represent locations on a spectrum: let’s call it “provenness”.
The author’s problem boils down to subjectivity - everyone positions different practices in different places on the provenness axis. The upshot of that is when one person says “we should do this, it’s obvious and/or it’ll definitely help” another person hears “we tried it once, you should try it too!” and then everyone has a bad time.
Then it gets confounded by everyone calling everything best practices - no matter how long ago or unproven the practices might be.
What would be handy is some generally agreed-upon yardsticks for graduating practices into or out of best practices status, plus better terminology to cover the spectrum of provenness so more sophisticated discussions can be had that account for the nuance and we don’t all talk past each other..
But then analyst companies wouldn’t get to make their glossy 2x2 charts, so it probably won’t happen.
I don't think that the issue is with "best practices," or any other type of dogma.
I think the main issue, is that companies tend to hire folks that aren't especially skilled at what they do, and rely on excessive structure, to compensate, or that they don't stay around, long enough, to get comfortable with the structure.
This can apply to both newer folks, who don't understand the system well enough to effectively deviate, and ones with a lot of experience, who have allowed themselves to get so hidebound, they are afraid to deviate.
As I have gotten older, wiser, and more battle-scarred (often, from self-inflicted injuries), I have learned that "It Depends™" is the only true mantra for my work.
Usually, best practices/dogma/structure becomes important, when the codebase is being worked on by a team, and when there's the need to coordinate work between teams.
There's some type of work that just can't be done, without structure. I've done that type of work. Other work can be killed by too much structure. I've done that kind of work, as well.
Only in the last one you can either understand the reason, or ignore the rule because it doesn't apply to your situation.
And note I don't mean stable as in, not crashing. I mean it as not changing.
For a while, this was doable with java. For its warts, it gave a good foundation. Industry practice got caught up in start up enthusiasm, though, and that went out the window.
Similar could probably be said for Windows. I was not a fan of its model, but it provided a stable base for business apps for a long time.
[1]https://www.joelonsoftware.com/2009/09/23/the-duct-tape-prog...
Put another way, knowledge is knowing best-practices, but wisdom is knowing where and when to apply them. Unfortunately, most building software have only the knowledge and there is too little consideration for the fact that structure is not free, and considerations must be made for when velocity is the primary objective vs safety and adherence to best-practices.
It all comes down to architecture design in the end.
In every case where you want to say “best practice” there is a better alternative, which is to say “practice.” The concept of best is never needed or warranted, because practices are not subject to rigorous testing and review.
I have been an independent consultant and trainer since 1999 and not once have I taught or recommended a best practice.
I do have many opinions. I call them: opinions. I think my opinions are the best, but I can’t think of any reason that anyone else beyond my wife and dog should think so.
But as I got more senior, when asked by less experienced developers the best way to do something, my answers tended to increasingly start with: "Well, it depends...".
And that's the thing, there is no universal best practice for everything, there are solutions which are more often than not good enough, but as all solutions tend to be a trade off favouring a particular scenario over another, sometimes they're also highly inappropriate to the particular circumstances.
Another term for someone trying to blindly apply supposed best practices is "cargo culting".
In summary, there is lot's nuance to software development and the particular circumstances it's being applied to meaning that you need to understand the trade offs of particular solutions to see which one makes the most sense for a particular situation.
I think that’s what this article is basically saying. And I agree.
As always it's a matter of context. If you have a low level language like C without any automatic cleanup having an out label to goto which cleans up in all cases makes a lot of sense.
There's always some reasoning behind those rules, sadly rarely talked about directly. You should check if that reasoning applies to you and weigh the benefits against the costs. A lot of time it's just doing what everyone else is doing, which is a very fine reason, as it makes onboarding new developers easier.
The real question is how do we prevent best practices to be perverted and I fear the answer is having the right people in the right places. The one best practice to rule them all: Have knowledgeable balanced people who know when to break the rules.
I've worked too often with people who think they know better
They do not
Straw men do not change the fact that "best practices" , especially the ones quoted, are very good.
No sensible person is saying "never use globals". We caution you to think very carefully before you do, only for truly global state.
I am suffering from inherited code, written by a very good programmer, who got lazy with globals and comments. Too many of the former, too few of the later. What a nightmare
This article is arrant nonsense
I still like Postel's law, but don't imagine for a second it's a 'law' with the kind of authority the article implies, and didn't enjoy the article's slime about people who like it!
The bigger issue is that developers (me included) are usually making the decisions in their own heads. Usually the reasons are quite ok but they are not really said out loud or documented.
I've been stumbled upon this as both developer trying to get their code approved and when doing a code review.
For the developer it feels super annoying that somebody nitpicks about things which the developer has probably gone through in their heads already and ended up with the resulting solution. Just like Martin in the post complains and reacts passive aggressively towards reviewers mentioning these things.
For the code reviewer it feels like the developer is being sloppy or doesn't care about our common way of doing things thus increasing the need to nitpick and explain so that the developer understands how it should be done.
The solution for this is actually quite easy: document in the comments and in the Pull Request _why_ you're breaking team's / company's guidelines and why you think it's warranted for solution for this case. This seems to remove quite a lot of friction.
Oh and of course it doesn't mean that the guidelines should be broken all the time just because one thinks this kind of stuff is for "idiots|assholes". When working as a team, we need to adhere to common way of working for most of the time.
- Use source control?
- Have build automation?
- (at least some) automated testing?
- Protect data structures accessed concurrently with a mutex?
- Have backups?
I wouldn't say there isn't some imaginary situation where you'd do something different, but it's safer to fall back to doing the above in most situations.
That said many people make up "best practices" or use them without understanding the circumstances to which they apply.
Most of these "best practices" have valid opposing camps anyway. There's DRY, but there's also "a little copying is better than a little dependency". Both are valid in different contexts.
But if I can't understand why I should do that instead of something else I've thought of, then I'll do it my way thank you.
In many cases, being predictable is better for future maintenance than forging your own path, even if the custom solution is "better" against all (current) metrics.
"Best practices" is a really good tool if you use it in the correct context.
Books like Code Complete are useful tools but not bibles.
Just like everything on the internet: it's just another person's opinion. What matters is what works (i.e. makes you money).
I tried to have the grammar checked by chatgpt but it was too challenging
I'm actually not even convinced that this is a good rule. When it's explained it makes sense on the surface. I also think that since beginners to programming use global variables, they come to the conclusion that it must be universally bad since that's what their beginner self did.
Having work on codebases with most state being being stored as global variables (in a single namespace at that) is manageable at worst and easy to develop on at best, assuming certain conventions are followed.
There was a culture of best practices zealots that had an uncanny resemblance to organized religion. All the answers have been written down for us, and everything that goes wrong is because of arrogant, misguided people who decided to trust their own fallible thoughts instead. Their faith was strong enough to survive any project, no matter the outcome.
https://en.wikipedia.org/wiki/Wikipedia:Emerson_and_Wilde_on...
(This is relevant to the extent that programming is as much art as science/engineering.)
Recently I was told that Hungarian notation was "best practice" and I must use it.
for example:
- use source control
- don't put spaces in file names
- camelcase is better than underscores in variables
- vi not emacs
some are really best practices, some are controversial choices someone is pushing.
Some places I've worked with good policies deliberately left some open. And made choices earlier on troublesome ones like spaces not tabs.
I think the choosing or defining vs not choosing is what companies should do to define themselves.
It is an error to throw out every best practice and reconsider everything just as it is to blindly follow the best practices.
IMO it’s best to apply the best practices by default and question them as they are used. Essentially trust but verify. Assuming they are right most of the time you get the benefit of speed. Assuming some of them are wrong, it still leaves room to course correct.
Related
Holding a Program in One's Head (2007)
The article highlights the cognitive processes in programming, emphasizing mental retention of code, the impact of distractions, and advocating for smaller teams and independent work to enhance creativity and understanding.
The Open Source Project Maintainer's Guide
The article humorously critiques ineffective open source project practices, suggesting counterproductive methods like using uncommon version control systems, ignoring bug reports, and prioritizing features over fixes, while advocating for better management.
Software development topics I've changed my mind on after 6 years in industry
The author reflects on their software development views, emphasizing typed languages for diverse teams, the importance of architecture, context-dependent best practices, and questioning the necessity of many project managers.
The Rise of Worse Is Better
The text contrasts two software design philosophies: the MIT approach, which values simplicity and correctness, and the worse-is-better philosophy, which prioritizes implementation simplicity, suggesting a need for reevaluation in the Lisp community.
Build systems, not heroes
The article highlights the need for system-based approaches in enterprise programming to reduce risks from personnel changes, ensure consistent quality, and improve workflows, despite potential resistance from individuals.