Trite and worthless. I've never yet seen a project that got perfect (or attempted to do so and ever shipped or delivered) and it is almost never a goal.
The tug of war is more often between putting unfinished things into production and some random deadline set by a person who knows nothing about the required amount of work to have a correct result. (Much less decent or maintainable.)
Not negotiable or adjustable too.
Even the sc(r)um approach of cutting features has limitations. At some point the customer will just be unhappy.
It's just a blog post about what he has observed as a common problem with teams falling behind. I think it's a little much to call it worthless.
Excessive focus on unimportant details is a real problem. Everybody probably naturally focuses either too much on details or too little, and this person recently ran into some teams that focused on them too much, preferring to polish features the customer didn't care about rather than finishing the product.
I don't think that's true. For example, it doesn't get much more foundational than glibc and that isn't perfect[1]. There's definitely a level of quality than needs to be reached, but that's some way short of perfection. Sometimes it's more useful to move forwards despite problems than to wait for them to be fixed.
I think most of what he says is correct, but it doesn't seem to address the actual problem I run into. The problem I see with my group's projects is not that we're trying to make it perfect. That almost never happens. Instead, management wants us to "just get it done," and "stop wasting time planning," and we end up with something that doesn't work well and is hard to maintain. Where a few days of pre-planning would have pointed out some areas where we were likely to get stuck and given us enough foresight to think up a better (but not perfect) architecture that we could implement in the time allotted. It still wouldn't be perfect, but it would be good instead of bad, which is what we end up shipping usually.
What I've found is that those days of pre-planning can be hit or miss. Yes, you might uncover a design flaw or missed requirement that would have set you off in the wrong direction. However, a prototype implementation is much more likely to uncover those same flaws, and probably also a few that you never would have found without building a prototype. I've found the prototype approach leads to a far higher likelihood of success. I think the real challenge with it is getting management to understand what is a prototype and what is a finished product, the danger being that you ship the prototype.
Of course, this is all highly dependent of the nature of your work and length of development cycles. But if you're shipping in weeks, I'd wager you should be planning for hours at a time, not days.
well, yes and no. The apollo program operated on a tick-tock schedule where they did progressively harder missions. I interpret this as a series of proof-of-concept deliverables which allowed the team to develop expertise.
Then later they could define & hit their tolerances for orbital mechanics, fuel budgets, system redundancy.
Same deal with faraday / maxwell / einstein. The experimenter (faraday) measured & applied new phenomena, then maxwell came up with general laws, then einstein figured out their implications.
This is straight from the cowboy coder's mouth. This is Philistinism, plain and simple.
> "...deliver something, anything...", no need to make it good, "teams make things better," anyway.
No, no, and no. If you want to scale a team you have to deliver quality code.
The cowboy coder spews out code, screams "see it works!", and then moves on to produce more diarrhea for "the team" behind him to clean up, "make better"...
When one realizes they do not yet have a skill (such as producing quality code), it is tempting to scream "quality/perfection is a heresy" because this is much, much easier to say than the labor it takes to develop the skill.
> It’s hard to see more than a week out because anything that takes more than a week to build involves R&D.
Wrong, wrong, and wrong. MOST of what we do as practitioners (for those that have been doing it for at least some time) is NOT novel. Estimation is a skill. Estimates can be extremely accurate for those of us that have developed that skill.
It is much easier to say "estimation is worthless" when it is a skill that you have not yet developed. Because it is only developed through (often frustrating) practice.
Record the time it takes to do your work. Notice the patterns of problems that you face and how often they repeat themselves.
---
Perfection per se has its hazards but in no way should that truth get us off the hook from developing ourselves and doing our work well.
This post is nothing but dangerous to the nascent programmer-practitioner as it attempts to lull them away from what is possible and the work it takes to get there.
Perfection is not attainable, but if we chase perfection we can catch excellence.
-- Vince Lombardi
Some new programmers need the advice to spend longer improving their code before sharing it; some need the opposite advice.
Unfortunately, some people who dispense advice pick one of those "directions" and argue strongly for it, rather than trying to describe how to recognise when you've got the balance right.
Sadly a lot of people have a hard time understanding nuance and middle-grounds. In programming or in anything else.
If your code is to be thrown away in one week, why make it perfect? If you have to maintain it for years, why make it a pile of shit? Funnily enough you can't often predict the lifetime of code.
Trying to attain perfection is good advice in a professional environment.
OTOH for side-projects, especially for people who have trouble finishing things without external motivation, it can be more useful to just get something done. Without the get-it-done mentality it's possible to obsess over the architecture, libraries, tech stack, deployment, test automation ad infinitum until you've lost enthusiasm for the project. It's great that you learned a lot of new tech but also slightly sad that the world will never see the idea you were so excited about 3 weeks ago.
This is the strategy that I prefer. I aim to deliver version 1 of my side projects within 3-4 weeks. After working on it for too long without delivering, I lose interest. I fix the time and budget of the version, not the scope. Unfinished features are cut out of the version 1. I focus on the core features. There will always be time to add extra features in the future.
Most people are afraid of launching because they don't want to be judged. That's why they delay the launch. I prefer giving my software to a handful of real users as soon as possible. So that they can test and give me feedback. There will always be bugs in software. Show me a popular software product and I will give you a list of over 10,000 bugs which were reported in its lifetime. What matters is the speed in which you fix them. If you created version 1 of the product, you wouldn't waste more than a day fixing all bugs reported on first day.
> The cowboy coder spews out code, screams "see it works!", and then moves on to produce more diarrhea for "the team" behind him to clean up, "make better"...
This resonates with me, and I hope I'm better than that. I don't know if I am. Some metrics might suggest so, but who knows.
Over the last couple of years, I've been working with a repeating pattern. Teammates have a problem, but the problem can be split into 20% - 40% hard / algorithmic / architectural issues, and something between 60% and 120% other detail-work once the hard parts and a couple of easy parts as examples are done.
So, I've grown to tackle and solve the hard parts, and give people a small chunk of software so they can solve their problem on their own, as long as I help them a little along the way. This is powerful if you have a strong understanding of the problem to solve, and a couple of open-minded team-mates. And it helps everyone to grow on a technical level, making further problems easy.
However, this requires care, communication, a strong understanding of the issue, support for the solution... By now, people ask me for to handle the hard parts, and I can just dump them a repository with a README and a rough solution. But that was a long way, and giving less support, less care to do the right thing, and doing less to build trust with the team will lead to a catastrophe. And interestingly enough - oversupporting would also lead to problems.
This sounds like the inverse of cowboy coding. The classic cowboy move is to tackle all of the easy parts incohesively, so the end program does may three quarters of what it is supposed to. Unfortunately implementing the last quarter will usually require re-writing large parts of the original code over years.
Sometimes the cowboy will linger around to try keep the unshippable code as-is. :( I do not understand why.
If $( cat $your_code | grep '//' ) results in something that does a good job describing the code then you're doing a good job.
If you think you're documenting way too much then it's about right. The people picking up your source years after you've left the company will need that much documentation. Documentation also breeds more documentation. When someone goes in and changes something they're far more likely to document it if their change makes existing documentation/comments incorrect.
Programming languages aren't just used to tell a computer what to do. They are languages (albeit simple ones with limited expression available).
People who learn a second human language often fall back on a crutch known as "code switching". With code switching, when you don't know how to express something in the language you are learning, you switch back to your native language. This can often help people develop more fluency because they don't sit around concentrating on trying to find the correct term. They can say the parts that are difficult in their native language and then move on to the rest of the conversation.
However, code switching ultimately slows down your progress as a language learner. If you don't know how to express what you want with the correct grammar or vocabulary, it's usually better to try to find a different way to say it. By doing this you exercise your ability to be flexible in your speech. The code switcher tends to hit a ceiling very quickly and never becomes able to express themselves in the new language -- because they never have to. Finding alternate ways to express yourself is often frustrating, slow and embarrassing, but will help you in the long run.
Comments are like code switching. It's really helpful when you've written some code and you think, "I'm not sure that people will be able to understand what this means". It helps you get unstuck from your current position and to move on to the next thing, safe in the knowledge that you have expressed what you need to express.
However, you can also look at the situation differently. If you write comments, then you do not have to express yourself clearly in the programming language. It's easy to fall into the trap of thinking that it is unimportant to express yourself clearly because 1) you have comments (which are easy to write) 2) expressing yourself in code is hard 3) it will take a lot of time to learn how to do it well 4) you might fail and end up with difficult to read code.
These are all seemingly excellent reasons for writing comments, but they will also hold you back from being a better programmer IMHO. I prefer to avoid comments, using them as a technique of last resort. However, if someone says, "I don't understand your code" you have to take it pretty seriously and find a way to express yourself more clearly.
As a side note, this is one of those areas where reasonable people can differ. Of the issues that can cause conflict on a team, I find this to be one of the biggest. No matter what your personal opinion is, it's important to work as a team and do your best to please your teammates. Code is not for the writer -- it's for the reader.
You are not writing code for just you. There may be times when people fresh out of college who do not speak English as their primary language may need to understand your source.
There is often back-story that needs to be explained. Something as obvious as input sensitization may have a more specific meaning behind the specific implementation, for example a legacy Orcale DB client that chokes on certain special characters. A comment in a case like that can prevent you from getting woken up at 1am because a well meaning attempt to apply the same naming rules to schemas as you do to everything broke things.
If someone says they "don't understand your code" then either they suck at understanding code, you suck at writing it or both.
Comments are a tool to increase the speed and accuracy with which someone else can understand your code.
I don't really think this goes against what mikekchar said, though. Take your own example (the legacy oracle client):
The code you're using to escape those specific characters should ideally be written in such a way that its intent is obvious even to a novice reading it. For the novice, then, the question shifts from "WTF does this do?" to "why is this here?", which would be a great example what to actually write comments for: context.
Imagine you're writing some very math-heavy library. Ideally, I shouldn't be a language expert to be able to see what your code does. This still doesn't help me if I don't understand the underlying math, however. Even hints like "this operation is called XY and can be used to Z" may be very helpful if someone wants to get a hold of what it does. With that, you can look up literature for this specific part.
Yep. I don't disagree with either of you. I was really responding to the comment that your comments should form a kind of running commentary of the code (something which I completely bought into when I was younger, but then moved away from). There are certain things you can't express with code. I don't want to suggest that you stubbornly refuse to express it at all in those cases :-). It's just that it's a technique of last resort, not a technique of first resort (if that makes any sense).
With respect to code documentation, I am self-taught, and use thorough documentation because I feel it both reinforces my intent and gives me the experience of describing it to someone else. I get the benefits of teaching, while also sparing my S.O. hours of listening to me rant and rave about things she isn't interested in.
I dont have a mentor, so this has helped tremendously.
This is a good idea. One thing you might try is also to do the same thing with unit tests. Can someone discover the intent of the code from the tests? I have found this considerably trickier to do than it seems because there is a tendency to introduce a lot of noise with the tests in order to get good coverage. I personally found it illuminating to refactor the code and tests so that I get the same kind of coverage without the noise.
That depends. I've found I actually comment/document less now than I used to in the past, because I'm better now at writing self-documenting code. If you can read the code itself and it reads like a comment, you don't need to write the comment.
I see both code and comments as a three-way conversation between myself, the person reading the code (who may be future-me or someone else), and the compiler.
I think this post is aimed more generally than just at programmers. In my experience, I've found more perfectionism everywhere else in the business. Bias: I'm a programmer and I believe I take the time to do the job the best I can; most of my time is spent re-doing features that users have never used.
One thing to consider is that different types of projects have different "thresholds " of "good enough." This is also highly dependent on the available competition to your product. At this point, unless there is some fantastic new application, anything intended for use by "ordinary consumers" better be nearly perfect to even have a chance.
I've observed with user interface design that there is often a stark threshold between "usable " and "unusable", and that it takes a perfectionist mindset to reach it.
This is one of those conversations that has been going on for decades (if not centuries or millennia). If your life involves making something in private, then putting it out there for other people to see/buy/whatever, every such project requires you to decide when its done and ready for the world.
Getting it out there sooner can be appealing if time is a factor. Spending extra time perfecting it is appealing if time is not a factor. It's just two poles between which you set a cutoff point, and in team efforts everyone will not only have different ideas about whether time or quality is more important, but they will have different perceptions about what it even means to be closer to one pole.
You're always compromising something in engineering, no matter which pole exerts a stronger pull on you. Putting a flawed product out early might kill the product; you should've put the development time cutoff point closer to the 'perfection' pole.
On the other hand, spending extra weeks or months or years polishing something that ends up not being not quite what anyone wanted is also bad, because if you had just gotten something out there sooner, you could've spent the same amount of time iterating on it in response to feedback. Lots of extra time spent on something often also translates into getting locked into technical choices that can be more difficult to back out of later if necessary. So there's definitely something to be said for putting a simpler and less-polished product out sooner to get feedback and test your initial assumptions vs. reality.
I think these conversations never cease in part because so many people who argue about this stuff are treating it as a binary choice. They're not picking a cutoff point between two poles, they're picking a pole and going all in on it. In reality, they see different sets of pros and cons and weight them differently and see risk differently. The solution is better communication between people so that there is at least a shared set of known pros and cons. People might still not agree, but they can at least have the same conversation when weighing compromises.
People who get into binary thinking patterns about situations which no one person fully grasps are being rational in their own way; they just don't understand that they are compromising something else. In my experience, people rarely see things in black and white once they understand how the opposing side views the situation. Both sides are rational, they just have disjoints areas of knowledge and thus priorities.
Well, while I don't think perfectionism is always a bad thing and releasing 'any old thing' as quickly as possible it's always a good idea, I definitely see where he's coming from. There's a balance you have to strike here between 'done quickly' and 'done perfectly', and pushing towards either end can doom your project.
I mean, look at Duke Nukem Forever. The game spent 15 years in development because the creators were never happy with it, constantly felt it needed to be better than the competition and always fretted about what engine might be the 'best possible choice' for the title.
That wasted millions of dollars, years of people's lives and all manner of resources for a game that would have been better released after three or four years with a couple of sequels down the line.
And lots of non game examples exist there too. I'm sure you can name amazing systems that took so in development due to 'doing everything properly no matter the cost' that their nimbler competitors ate them for lunch.
At the same time, you can also likely remember many examples where products got released without enough care and attention put into the coding site (or quality control in general) and it just slaughtered their reputation and long term popularity.
It's a fine line you have to wander, and one that can sink a product or service if you go too far off track.
> People talk about executive functioning like it’s a general thing, but I’m just as helpless as my nephew when digging into a new codebase or project. Spending all your energy on details means having no attention left over to plan. Each problem you solve becomes an all-consuming distraction.
Maybe this works in the short term, but if your policy is always to "deliver something, anything", you'll find it harder and harder to deliver anything, and more and more bugs appearing when you do. You need to understand the meaning of the code to successfully change it. Code written following this "deliver anything" policy will tend to have unclear, inconsistent, or flat-out nonexistent meaning. Further changes written like this will keep eroding the meaning until you're left with a program that can only be understood in terms of what happens when you run it.
You can never be confident making changes to a program like this, because you don't have a coherent understanding of how each change will affect the system as a whole: all you know is how it will change the behavior when the system is run in a particular way. You don't have to be a perfectionist to understand this!
> Code written following this "deliver anything" policy will tend to have unclear, inconsistent, or flat-out nonexistent meaning.
Funnily enough, "quick & dirty" code also often seems to ignore obvious easy solutions to any given problem and instead pursuits more cryptic/unmaintainable ones.
That's the thing that bothers me the most when I'm encountering that sort of thing: It isn't just "a bit ugly" - more often than not it's hacked together using methods that merely almost work when there's a perfectly viable option that has been there since the 70s. And - on top of that - it usually even locks you in on those horrible decisions.
Example:
You have to configure a piece of software. The configuration is highly critical and must be maintainable and synchronizable between systems.
There are tools that put their entire configuration in a database and sell it as a feature. To sum up:
- You can't properly version said database
- You can't diff said database
- You can't grep said database
- Reading the config takes ages if you can't use a different shoddy tool
- Writing it manually is nigh on impossible
- Errors get very obscure since you have to provide tables and IDs as references
...then why the hell aren't we just using text files for that? You could even insert the text verbatim into a table record and be better off.
When I went through my toolmaker apprenticeship a long time ago, the first rule that our master hammered into our brains was "Not as accurate as possible, but as accurate as required".
The tool didn't work any better if the accuracy was better than specified, so trying to make it better was considered a waste of time.
It helped that the required accuracy was usually part of the specification, while software quality is mostly a subjective thing.
If everything is always changing, then the perfect happens only one moment in time and the next moment the perfect is gone. Secondly, you can only influence things to perfection and when they hit perfect, you got lucky. You cannot make it happen.
With design, there must be some way to be objective to evaluate a design. If there is no objective, then how can you establish, know and recognize what is perfect?
The merits of the advice aside, the foundation of his argument and the headline itself are wrong. What about Platonism? And the Sapir-Whorf hypothesis needs to die.
I guess this isn't meant to be a serious work of scholarship anyway, with footnotes like, "For the life of me I can’t remember where I read this."
44 comments
[ 7.0 ms ] story [ 80.5 ms ] threadThe tug of war is more often between putting unfinished things into production and some random deadline set by a person who knows nothing about the required amount of work to have a correct result. (Much less decent or maintainable.) Not negotiable or adjustable too.
Even the sc(r)um approach of cutting features has limitations. At some point the customer will just be unhappy.
Excessive focus on unimportant details is a real problem. Everybody probably naturally focuses either too much on details or too little, and this person recently ran into some teams that focused on them too much, preferring to polish features the customer didn't care about rather than finishing the product.
Perfection has its uses.
[1] https://sourceware.org/bugzilla/buglist.cgi?bug_status=__ope...
Of course, this is all highly dependent of the nature of your work and length of development cycles. But if you're shipping in weeks, I'd wager you should be planning for hours at a time, not days.
Modern heresy is applying anecdotal solutions to situations as learnings for all problems.
Then later they could define & hit their tolerances for orbital mechanics, fuel budgets, system redundancy.
Same deal with faraday / maxwell / einstein. The experimenter (faraday) measured & applied new phenomena, then maxwell came up with general laws, then einstein figured out their implications.
> "...deliver something, anything...", no need to make it good, "teams make things better," anyway.
No, no, and no. If you want to scale a team you have to deliver quality code.
The cowboy coder spews out code, screams "see it works!", and then moves on to produce more diarrhea for "the team" behind him to clean up, "make better"...
When one realizes they do not yet have a skill (such as producing quality code), it is tempting to scream "quality/perfection is a heresy" because this is much, much easier to say than the labor it takes to develop the skill.
> It’s hard to see more than a week out because anything that takes more than a week to build involves R&D.
Wrong, wrong, and wrong. MOST of what we do as practitioners (for those that have been doing it for at least some time) is NOT novel. Estimation is a skill. Estimates can be extremely accurate for those of us that have developed that skill.
It is much easier to say "estimation is worthless" when it is a skill that you have not yet developed. Because it is only developed through (often frustrating) practice.
Record the time it takes to do your work. Notice the patterns of problems that you face and how often they repeat themselves.
---
Perfection per se has its hazards but in no way should that truth get us off the hook from developing ourselves and doing our work well.
This post is nothing but dangerous to the nascent programmer-practitioner as it attempts to lull them away from what is possible and the work it takes to get there.
Perfection is not attainable, but if we chase perfection we can catch excellence. -- Vince Lombardi
Unfortunately, some people who dispense advice pick one of those "directions" and argue strongly for it, rather than trying to describe how to recognise when you've got the balance right.
If your code is to be thrown away in one week, why make it perfect? If you have to maintain it for years, why make it a pile of shit? Funnily enough you can't often predict the lifetime of code.
http://slatestarcodex.com/2013/06/09/all-debates-are-bravery...
How is such a condition even possible? This seems to be equivalent to describing, say, a libc, as "way more bug-free than can possibly be healthy".
EDIT: there is no way that someone could be combing through days-old posts just to downvote something within an hour of being posted. >:|
OTOH for side-projects, especially for people who have trouble finishing things without external motivation, it can be more useful to just get something done. Without the get-it-done mentality it's possible to obsess over the architecture, libraries, tech stack, deployment, test automation ad infinitum until you've lost enthusiasm for the project. It's great that you learned a lot of new tech but also slightly sad that the world will never see the idea you were so excited about 3 weeks ago.
This is the strategy that I prefer. I aim to deliver version 1 of my side projects within 3-4 weeks. After working on it for too long without delivering, I lose interest. I fix the time and budget of the version, not the scope. Unfinished features are cut out of the version 1. I focus on the core features. There will always be time to add extra features in the future.
Most people are afraid of launching because they don't want to be judged. That's why they delay the launch. I prefer giving my software to a handful of real users as soon as possible. So that they can test and give me feedback. There will always be bugs in software. Show me a popular software product and I will give you a list of over 10,000 bugs which were reported in its lifetime. What matters is the speed in which you fix them. If you created version 1 of the product, you wouldn't waste more than a day fixing all bugs reported on first day.
'Great artists ship' - Steve Jobs.
This resonates with me, and I hope I'm better than that. I don't know if I am. Some metrics might suggest so, but who knows.
Over the last couple of years, I've been working with a repeating pattern. Teammates have a problem, but the problem can be split into 20% - 40% hard / algorithmic / architectural issues, and something between 60% and 120% other detail-work once the hard parts and a couple of easy parts as examples are done.
So, I've grown to tackle and solve the hard parts, and give people a small chunk of software so they can solve their problem on their own, as long as I help them a little along the way. This is powerful if you have a strong understanding of the problem to solve, and a couple of open-minded team-mates. And it helps everyone to grow on a technical level, making further problems easy.
However, this requires care, communication, a strong understanding of the issue, support for the solution... By now, people ask me for to handle the hard parts, and I can just dump them a repository with a README and a rough solution. But that was a long way, and giving less support, less care to do the right thing, and doing less to build trust with the team will lead to a catastrophe. And interestingly enough - oversupporting would also lead to problems.
Sometimes the cowboy will linger around to try keep the unshippable code as-is. :( I do not understand why.
If you think you're documenting way too much then it's about right. The people picking up your source years after you've left the company will need that much documentation. Documentation also breeds more documentation. When someone goes in and changes something they're far more likely to document it if their change makes existing documentation/comments incorrect.
But I agree entirely. I go back to things I did even a year ago and desperately wish I had documented more.
Now I'm left wondering if that makes a point for or against the OP's arguments. ;-)
People who learn a second human language often fall back on a crutch known as "code switching". With code switching, when you don't know how to express something in the language you are learning, you switch back to your native language. This can often help people develop more fluency because they don't sit around concentrating on trying to find the correct term. They can say the parts that are difficult in their native language and then move on to the rest of the conversation.
However, code switching ultimately slows down your progress as a language learner. If you don't know how to express what you want with the correct grammar or vocabulary, it's usually better to try to find a different way to say it. By doing this you exercise your ability to be flexible in your speech. The code switcher tends to hit a ceiling very quickly and never becomes able to express themselves in the new language -- because they never have to. Finding alternate ways to express yourself is often frustrating, slow and embarrassing, but will help you in the long run.
Comments are like code switching. It's really helpful when you've written some code and you think, "I'm not sure that people will be able to understand what this means". It helps you get unstuck from your current position and to move on to the next thing, safe in the knowledge that you have expressed what you need to express.
However, you can also look at the situation differently. If you write comments, then you do not have to express yourself clearly in the programming language. It's easy to fall into the trap of thinking that it is unimportant to express yourself clearly because 1) you have comments (which are easy to write) 2) expressing yourself in code is hard 3) it will take a lot of time to learn how to do it well 4) you might fail and end up with difficult to read code.
These are all seemingly excellent reasons for writing comments, but they will also hold you back from being a better programmer IMHO. I prefer to avoid comments, using them as a technique of last resort. However, if someone says, "I don't understand your code" you have to take it pretty seriously and find a way to express yourself more clearly.
As a side note, this is one of those areas where reasonable people can differ. Of the issues that can cause conflict on a team, I find this to be one of the biggest. No matter what your personal opinion is, it's important to work as a team and do your best to please your teammates. Code is not for the writer -- it's for the reader.
There is often back-story that needs to be explained. Something as obvious as input sensitization may have a more specific meaning behind the specific implementation, for example a legacy Orcale DB client that chokes on certain special characters. A comment in a case like that can prevent you from getting woken up at 1am because a well meaning attempt to apply the same naming rules to schemas as you do to everything broke things.
If someone says they "don't understand your code" then either they suck at understanding code, you suck at writing it or both.
Comments are a tool to increase the speed and accuracy with which someone else can understand your code.
The code you're using to escape those specific characters should ideally be written in such a way that its intent is obvious even to a novice reading it. For the novice, then, the question shifts from "WTF does this do?" to "why is this here?", which would be a great example what to actually write comments for: context.
Imagine you're writing some very math-heavy library. Ideally, I shouldn't be a language expert to be able to see what your code does. This still doesn't help me if I don't understand the underlying math, however. Even hints like "this operation is called XY and can be used to Z" may be very helpful if someone wants to get a hold of what it does. With that, you can look up literature for this specific part.
I dont have a mentor, so this has helped tremendously.
I see both code and comments as a three-way conversation between myself, the person reading the code (who may be future-me or someone else), and the compiler.
Sometimes it makes sense to rapidly spew out brittle code. Other times it makes sense to delay until you get it right.
What's important is being in control of the situation. Know what you're doing and why. Know the tradeoffs and commit to them.
I've observed with user interface design that there is often a stark threshold between "usable " and "unusable", and that it takes a perfectionist mindset to reach it.
Getting it out there sooner can be appealing if time is a factor. Spending extra time perfecting it is appealing if time is not a factor. It's just two poles between which you set a cutoff point, and in team efforts everyone will not only have different ideas about whether time or quality is more important, but they will have different perceptions about what it even means to be closer to one pole.
You're always compromising something in engineering, no matter which pole exerts a stronger pull on you. Putting a flawed product out early might kill the product; you should've put the development time cutoff point closer to the 'perfection' pole.
On the other hand, spending extra weeks or months or years polishing something that ends up not being not quite what anyone wanted is also bad, because if you had just gotten something out there sooner, you could've spent the same amount of time iterating on it in response to feedback. Lots of extra time spent on something often also translates into getting locked into technical choices that can be more difficult to back out of later if necessary. So there's definitely something to be said for putting a simpler and less-polished product out sooner to get feedback and test your initial assumptions vs. reality.
I think these conversations never cease in part because so many people who argue about this stuff are treating it as a binary choice. They're not picking a cutoff point between two poles, they're picking a pole and going all in on it. In reality, they see different sets of pros and cons and weight them differently and see risk differently. The solution is better communication between people so that there is at least a shared set of known pros and cons. People might still not agree, but they can at least have the same conversation when weighing compromises.
People who get into binary thinking patterns about situations which no one person fully grasps are being rational in their own way; they just don't understand that they are compromising something else. In my experience, people rarely see things in black and white once they understand how the opposing side views the situation. Both sides are rational, they just have disjoints areas of knowledge and thus priorities.
I mean, look at Duke Nukem Forever. The game spent 15 years in development because the creators were never happy with it, constantly felt it needed to be better than the competition and always fretted about what engine might be the 'best possible choice' for the title.
That wasted millions of dollars, years of people's lives and all manner of resources for a game that would have been better released after three or four years with a couple of sequels down the line.
And lots of non game examples exist there too. I'm sure you can name amazing systems that took so in development due to 'doing everything properly no matter the cost' that their nimbler competitors ate them for lunch.
At the same time, you can also likely remember many examples where products got released without enough care and attention put into the coding site (or quality control in general) and it just slaughtered their reputation and long term popularity.
It's a fine line you have to wander, and one that can sink a product or service if you go too far off track.
This.
By my reading the old definition of 'perfect' is "fulfills the important criteria of being done".
For a boat that meant "didn't sink" (so done is like completed, while perfect is 'completed and useful').
You can never be confident making changes to a program like this, because you don't have a coherent understanding of how each change will affect the system as a whole: all you know is how it will change the behavior when the system is run in a particular way. You don't have to be a perfectionist to understand this!
Funnily enough, "quick & dirty" code also often seems to ignore obvious easy solutions to any given problem and instead pursuits more cryptic/unmaintainable ones.
That's the thing that bothers me the most when I'm encountering that sort of thing: It isn't just "a bit ugly" - more often than not it's hacked together using methods that merely almost work when there's a perfectly viable option that has been there since the 70s. And - on top of that - it usually even locks you in on those horrible decisions.
Example: You have to configure a piece of software. The configuration is highly critical and must be maintainable and synchronizable between systems.
There are tools that put their entire configuration in a database and sell it as a feature. To sum up:
- You can't properly version said database
- You can't diff said database
- You can't grep said database
- Reading the config takes ages if you can't use a different shoddy tool
- Writing it manually is nigh on impossible
- Errors get very obscure since you have to provide tables and IDs as references
...then why the hell aren't we just using text files for that? You could even insert the text verbatim into a table record and be better off.
The tool didn't work any better if the accuracy was better than specified, so trying to make it better was considered a waste of time.
It helped that the required accuracy was usually part of the specification, while software quality is mostly a subjective thing.
A witty saying proves nothing -- Voltaire.
I guess this isn't meant to be a serious work of scholarship anyway, with footnotes like, "For the life of me I can’t remember where I read this."