Anti-patterns and malpractices in modern software development (2015)
web.archive.org
web.archive.org
“business people” most often do understand what makes the money flow through their company (and into engineers’ bank accounts) and they typically make decisions in order to maximize good business outcomes. Sure they don’t understand the technical details of an engineer’s work, but the engineers are far from understanding all of the things that must fall into place besides lines of code in order for their paycheck to clear. It’s not always vital to the business to have a good code base. Also, for better or worse, if an engineer is not of the variety I listed above, they are replaceable in the eyes of the business.
(fwiw I’m a director-level engineer so I’m technical but bordering on being a “business person”)
There is a difference between complaining, voicing opposition and articulating trade-offs less technical people may not be familiar with.
Eventually customer got tired of having to defend how many statuses he wanted in combobox or what process their company want to use.
By that I want to say, there is definitely such a thing as programmer not willing to consider business point of view for a second and thus being impossible to work with.
It is vital to understand business needs. A lot of times businesses want changes that are hard, and very hard to implement. It is our responsibility to work with the customer to come up with a solution. The customer must accept the consequences that come with their requested change.
Unfortunately, some things are impossible to do. It is never good to be the bearer of bad news - I have myself told that we cannot do it this way, but I have always given a thorough explanation of why it is impossible and suggested workarounds and alternatives. I think sometimes this behavior can be the difference between the perception of being impossible to work with and helpful.
Truth is, it takes a lot of effort to balance your work against the ever-changing set of requirements coming from your stakeholders.
By questioning in don't mean having honest questions nor trying to understand, but being convinced that there must be mistake and forcing customer to defend every tiny choice.
And sometimes the customer wants radiobox instead of combobox are just wants to have it without having to spend 20min on meting to defend the choice.
For example, password requirements. Many companies are not aware of the latest best practices and guidelines and request that we block browsers from generating or remembering passwords in password fields. Or they give us a list of draconian password requirements that are clearly debunked by the latest guidelines.
Or they ask us to basically break the HTML spec.
Like I tell my four year old son, I'd love to get a million dollars but I'm not going to get it because I stamp my feet and demand it.
Trade-offs need to be made on both sides. I agree that an engineer that doesn't provide alternatives when a customer demand is not technically feasible should be corrected. However the customer should be prepared to choose from those alternatives or change their demands as well. The first step to success is shipping and the most common reason for software projects shipping late is a failure to start. I'm not against firing bad customers.
It's much easier to ship without a contentious feature and figure out how to add it later than to delay shipping (for certain features within reason, of course -- please don't ship half-baked security libraries or aviation control software).
I was specifically talking about situation where requirements are possible and not ambiguos. And where engineers starts "knowing" customer is wrong and keep knowing it despite it regularly turns out it was enginers lack of domain knowledge.
There is no trade off between these two situations.
I don't know what you mean by breaking html spec. Browsers keep it and we work either with it or around it?
re: HTML -- I've had strange requirements come in that required us to work around the HTML spec in order to get the UI to work they way they wanted. We eventually found a better solution...
but the point was that not all requirements are golden; sometimes the customer is plain wrong, ignorant, and stubborn.
If the problem is that the issue hasn't been explained well enough then the developers need to work harder to better explain what the problems are and why they're problems.
If the problem is that the business person doesn't have the necessary background to understand the issue then you have a huge problem. That person is going to be a problem at every step. I don't envy anyone in that situation. In the past 25 years of development I've never actually encountered that situation though.
Unfortunately, some business people are compensated as direct function of revenue (growth), even though they have to pull engineering levers to obtain that delta in revenue.
For a lot of these people, once they’re convinced that doing X will lead to growth, no explanation will convince them that it isn’t worth it.
Make sockets as first priority and then write tcp stack as "unneeded"/postponed is quite frequent from a bussiness standpoint. Not complaining about situations like this is just hurting the bussiness.
The core problem is that too often business needs are dogmatic and management is too entrenched to fix it.
This is the reason why so many large-scale IT/digitalization projects end up colossal clusterfucks: no one on customer side has the spine to say "our processes and workflows were made in an age where people did things by hand, let us modernize them while we're already at it".
> clearly articulate trade offs to stakeholders
may be the constructive cousin of complaining.
You're on the edge of contradicting yourself.
If the business environment is fast paced, ie your development process for ingesting features and specifying behavior is ad hoc, ("we are agile/do scrum, except we service requests from customers immediately as they come in instead of waiting until the next sprint") it's absolutely vital to the business to have a good code base.
Being able to make rapid changes without breaking everything requires a good code base. If your code base is full of landmines, you necessarily cannot send an average coder out to implement some average feature, because they'll necessarily have to (re-)teach themselves about half the idiosyncrasies of the codebase before they can do anything.
It's fine to have a shitty code base if your business environment moves stodgingly. ("You want a new form in the UI? OK great! We need a scope of work, a formal specification, we will charge you by the hour, you will need to pay us to recertify the entire product. Let's set up a meeting with contracting and legal next quarter to iron out the details.")
In my experience, the people who implement features quickly in a shitty codebases do so by breaking stuff in non obvious ways. This includes myself. This is fine for my organization because we only ship once every six months, and we only ship anything after two months of exhaustive manual testing. If the organization just decided, "we're a fast paced organization now, now we ship every two weeks" we'd lose all our customers fairly quickly as a result of the precipitous decline of the quality of our product.
I suppose fast paced business environment+shitty codebase is also ok if the goal is just to sell the company as soon as possible. But that's a personal objective, (and a selfish one) not a business objective.
All that is usually done at the expense of others - be it teammates or future maintainers.
It works great for MVPs and such, but falls flat on its face when you have to add new features to a three year old application, whose original creator moved on a while ago.
I once spent 6 months fixing someone else's MVP. Every bug fix exposed 2 more. I begged for a do over. Nope, we've invested too much money to abandon.
Once I understand the problem well enough, I banged out a full rewrite in two weeks. I had just one bug before release (one of the trig equations had the wrong sign, facepalm slap).
You had me until this statement. It's been my observation that "business people" are usually self-interested manipulators who hire people they don't need if it makes them look important, game/trick OKRs, hide all failures from their superiors (and would fire you if you went behind their back), often damage brand trust/equity to try to get good metrics for a quarter (e.g. google), willingly let massive problems (e.g. security holes a la equifax) fall on the floor rather than risk being associated with problem by helping.
Not all, but more than half.
To make it easier there really are only 2 business constraints: Time and Money. Everything can roll up to one or both of those.
I'd also like to note that asking an engineer to estimate a project, is work. That work (creating the estimate) takes both time and money. The more time and money engineers spend on creating an estimate, the more accurate (and valuable) it will be.
Here. This is an estimate for almost every business software project: Between $0 and $100MM. That took me no time and as a result, has no value.
The other end of that spectrum is an estimate with perfect accuracy and full value. Meaning -- we know, to the penny, what it is going to cost. An estimate like that is going to be EXPENSIVE and might even eclipse the cost of the entire software project.
Knowing that creating estimates take time and money, the question inevitably becomes "Well how much will it take to create the estimate?"
The answer comes down to: How much do you want to invest in it? Or better put: How important is estimate accuracy to you?
Business people decide the value of things, rely on that. "What is the dollar value of this to the business?" is a legitimate question to ask to a business person. If it's worth $1, then use my estimate above. If it's worth $1MM then the next question is: What percentage of that inevitable end value is it worth to spend on the estimate?
Most of the time the number that comes back is not derived from some magical corporate formula, it's gut feel. Which by the way is essentially arbitrary, which I wouldn't call useless. But let's call it what it is, it's a number that is palatable to the business to lose.
So, given that number, we now know how much time to spend. Your accuracy will directly reflect that amount. If we want to be more accurate, we'll have to spend more money.
Business people are responsible for the money and engineers can not manufacture more time.
Rely on both of those.
As a freelance programmer I had to learn this. Companies don't give anything about the language, the VCS, the LOC, spaces or tabs, or anything unrelated to them.
You just add value to the company by creating great software they can use. This also means software that can be maintained and updated.
Some people in this thread complain about the "They don’t complain about business constraints". But when you start complaining about their business constraints, how can you add value to their business? You can only add value when you think about how you can create something that works best for them to keep those constraints. And ofcourse this includes discussing constraints when you are sure you have a great idea to make them better, but most of the time other people thought better and harder about those constraints than you did.
Edit: maybe it is unclear what you mean by "business constraints". In my mind you are talking about the company business, but others might thing about programming business logic.
My anecdata for the last 15+ years doesn't support this claim.
Sometimes dumb people can still be lucky and make money (one place was dumb all around but their business was a unassailable monopoly, and another had 40 years of dumb customers who agreed to terrible annuities so failure would take decades to happen no matter what was done) and sometimes bad decisions or understanding in business or tech lead directly to failure.
There is no single type of success or failure in either business or tech.
But I create great insights. Whole new ways to see a problem. Making the intractable and complex simple and obvious with a novel mental model.
For instance, I replaced a high end CAD/Illustrator style print production workflow with a simple form. Answer some questions and out pops a production plan.
It took me 4 years to earn that insight. The entire industry modeled the flow information exactly backwards (https://en.wikipedia.org/wiki/Job_Definition_Format). It took me forever to overcome my initial misunderstand of the problem -- I mean really, how conceited am I to think everyone else is wrong and no one else thought of this before me -- and see the problem like the production workers do. I had to bridge the domains of print production and software design.
Alas, it's been a while since I've had a gig which could afford that kind of investment. My last gig, recommenders for fashion, which turned out to be a complete hoax, devs were slaves to JIRA, "just do 80%" and move on, throw everything away every 2 years, unless it's "legacy", in which case just suffer with it.
I wonder if there's much room left for dinosaurs like me.
Many engineers may cringe at this... but this is true. Code is only as good as it is able to fulfill a business need: that is help the organization meet its strategic goals.
Technical constraints - maintainability, security, performance,... - are really subservient to that principle.
That is, they aren't unimportant. Rather, their importance is relevant - or a priority - in so far that they help achieve the higher goals.
... but this isn't a universal maxim!
> Also, for better or worse, if an engineer is not of the variety I listed above, they are replaceable in the eyes of the business.
An employer/employee relationship is very much a business deal between humans. An employee sells expertise and potential for a fixed amount of time in exchange for a fixed salary. As with any deal, such business relationships extend beyond simple monetary compensation. Especially because employees subjugate themselves to the authority of their employer, making it inherently a skewed relationship.
When humans invest their time and effort in a venture, they hope to get a due sense of satisfaction and self-actualization from doing so. That's where aligning values makes all the difference.
What many business people fail to see is that employees don't identify themselves as resources, liabilities or labor. They see themselves as partners who hope to make a meaningful contribution, and they are willing to do so provided that they are treated as such: with a due sense of empathy and respect for their opinions, what motivates them to come to work each day; and so on.
If they don't get that, two things might happen. Either employees will walk out rather quickly, or - worst - they stay and will only give you the bare minimum of their efforts - living for the weekends - wasting both their own and your time.
It's true that companies aren't obligated to keep employees forever or that they can be let go if both parties want different things ...
... but publicly stating that any employer/employee relationship is "replaceable" without that nuance, is the shortest route towards foundering any hopes to attract potential hires who care about your business at all.
> They don’t complain about business constraints and they put out stellar work.
Given the above, humans will also factor in the moral and ethical side of what they are doing. And they can, will and should criticize those business constraints if those don't align with what they feel is "good" or "morally sound".
Business constraints aren't just limited to implementing some weird feature. That's just the output of a business constraint. Neither are styling rules or automated tests business constraints. Nope. it's far more then that. It's workplace culture as a whole. It's the shared values that are espoused on a day-to-day basis by everyone.
It's normal to have some level of conflict or tension as the net result is an ever-moving compromise.
Expecting that employees will never complain and only put out stellar work pretty much makes any healthy discussion moot. It's a non-argument as "stellar" is only meaningful in the eye of the beholder. All it does is create the perception that employees are seen as automatons.
Again, when employees pick up on this; they will either walk out or - worst - stick around and waste yours and their own time only doing the bare minimum to cash a paycheck.
In the short run, the bottom line of a company may reflect the financial benefits of optimizing for efficiency. But in the long run; not taking the human factor into account isn't sustainable at all. Neither for the employees, nor the business owners.
> Given the above, humans will also factor in the moral and ethical side of what they are doing. And they can, will and should criticize those business constraints if those don't align with what they feel is "good" or "morally sound".
My thought after reading the article was that the author seemed to consider writing good code, maintainable code, and having a strategy prioritizing long term over short term needs as moral imperatives. Or at least the words and terms used were ones I often hear and use when discussing ethics and morals.
Which made me think, do many engineers consider these things as ethical decisions, rather than just business choices?
Personally I enjoy being involved in strategic decisions, both providing input and opinion - but I also see the value in adhering to a strategy once decided even if it isn’t the one I’d advocate for if it was up for discussion. For ethical decisions I’d reason differently - it’s not ok to break laws or destroy lives (etc etc) just because a business decision said so.
I don't think the article's author said this. In my eyes he meant it more like "at least give us SOME breathing room to do our best engineering work!" -- meaning give some time for refactors, for changing tooling, for stepping back for 1-2 months and just looking at the whole thing in general.
Creativity needs time for pondering and reflection. Chasing ruthless and practically impossible deadlines while having to systemically ignore everything that made you a good engineer in the first place makes for a toxic employee<->employer relationship. And one that rarely ends well.
When you only have short term goals, sustainability is doesn't make sense.
- is an IDE open on your desktop right now?
- how many commits have you done this year?
Talking about code and software isn't anywhere near the same as being a programmer. If I am wrong about you, I apologize; you are the exception.
Instead, I think we need to learn how to measure and quantify the value of a good codebase and good practices, and communicate that to the business. Google's error budgets are a step in the right direction here, but I think there's a lot more that can be done.
I've used the analogy of kitchen / food hygiene. It doesn't necessarily improve the taste of the food but it prevents cockroaches and death by food-poisoning.
Not to mention being shut down by the health department, losing money and requiring new staff to learn non-standard ways of doing thing which takes longer AND causes an over-dependence on long term employees who are the only ones who 'know how to do that'.
Better fung shui? No, more like 'not cutting corners'.
But there must be some quantity or term, with a nice memorable ring to it, that could get this across and at least let business people make decisions with full information at hand. Granted, any such numbers delivered in that guise would be wild guesses. But still, better than nothing.
Edit: However, I've since realized that the notion of "story points" and "velocity" already sort of provides a way to get this across if used carefully.
As the article points out, management can be short sighted- they want to deliver on their roadmap this quarter or half (because that is what they are paid for).
I don't know what the answer is, I struggle with this. Testing has some promise here: if we can deliver (failing) tests early on that demonstrate progress toward the roadmap, and use those to show progress to the business and help them hedge risk, we can use tests as a forcing function for quality - testable code, especially for business processes, is usually good code.
"8 points + three support cases per week" for making a new feature without fully thinking it through.
Or
"32 points + misconfigurations every other month" for including a complicated feature that can more easily be abused.
Or
"We can go with our current best guess, and the effort of that is maybe 2 points + potentially 12 points later if it turns out we were wrong. Contrast this with 6 points to be certain of doing the right thing now."
In my experience, this is highly appreciated in environments that take you seriously, listen to you, and understand what "estimation" means,
Edit: Expanding with my previous thoughts on this - as a software architect I've explained my role to management by saying it's like I work in an agile team, but the waterfall is in my head - someone needs to keep the architecture together and drive it towards green pastures where it keeps great flexibility for developing future anticipated features without giving up stability.
Tech debt needs to be handled, or else your software won't be maintainable in the long term and new features will cost much more and put the system in risk even more.
And there is a nice slide about it: https://www.slideshare.net/cairolali/resolving-technical-deb...
(In case you are wondering, the circle means, you're past any maintainability. Go to start, rewrite. If your client or manager wants to avoid it, he/she should plan for refactoring).
At least the first time you tell them. Maybe the issue is much bigger than just communication. Perhaps they also realize that they don't work for, or will get rewarded for, far future profits and benefits.
Not really.
What you're missing is called risk. risk with respect to missing the deadline and long term risk when doing a sloppy job.
Business people understand risk, yet software developers go through all this effort to talk about story points and velocity.
Bottom line, I frequently question much of what is being sold as developer productivity these days. It seems in my experience "this code is ugly/garbage/etc" is simply translation for "I don't understand much of this code". Engineers that truly understand the code base just go and fix it, usually with commits that are either small one or two line bug fixes with long commit messages describing how the system is failing and what is actually being fixed. Alternatively, they have "cleanup" patches that have extremely high removal/add line ratios which are replacing large chunks of difficult to understand code with small pieces that are easier to understand, and long commit messages detailing where the redundant functionality was. Very rarely are these changes to a different language/toolkit. But the evidence of skill in both these cases just about never include followup patches to "fix" new problems introduced by the previous round of fixes.
In practice I think the best approach is to primarily refactor incrementally in service of ongoing work; management doesn’t need to approve this, you just build it into your estimates as an IC. If technical debt is being taken on call it out early and loudly and secure cleanup budget in advance if possible.
Beyond that recognize that big rewrites are rarely justifiable. Even if a code base is complete shit, it’s most likely not worth it to rewrite. As an engineer this reality may put you in a lose-lose situation. Learn to separate your personal feelings and innate desire for order, and make an objective call on whether the code is workable and start looking for a new job if not.
Since #bugs is strongly correlated with loc I'm thinking this might turn out to be very low in signal -- so much so that you might instead just throw a dice to determine the "code quality" of each project, if using this metric is the alternative.
I'm all for reducing the defect rate, I'm just not convinced optimising bugs/kloc is meaningful.
And everything being mostly equal, it could be a reflection of code maturity more than anything. The more mature product may have a higher bug/loc ratio only because more of the bugs have been found.
Which is why I mention there are metrics, but they all seem to have major problems.
Software can limp along broken without anyone noticing for far longer.
Directly measured, the engine cylinder walls will grow wider and compression will be lost. Indirectly we can do an oil analysis and see the metals deposited.
One of the reasons we do not understand the cost of low internal quality code is that we do not know the "spec". Defect rates is one proxy measurement, but it's hard to know if it's just "bad programming" or "bad internal code quality" ...
no, it's because the engine will seize and fail if you don't change the oil, and it's readily apparent to everyone when it happens.
If it's on a spreadsheet that their boss can see saying that they asked me to spend 0% of my time on quality then I'm ok with it. If they can justify putting that zero down then presumably there IS a good reason.
If they're going to put me under implicit pressure to deliver as many features as possible and then cry havoc later when they get bugs then I'll lack sympathy.
Product managers are often resistant to the idea of tracking this number, however, since it provides a new angle through which they can receive flak from above.
I'm not saying that clean code is a waste of time - it is incredibly valuable! I'm an engineer, and I value good architecture a lot. I'm saying that to get organizational support for it means that we have to get better at demonstrating that value to non-engineers, which will both hold us as engineers accountable to working on the highest impact things (is delaying features worth the potential short term ARR loss or slower customer acquisition? We should have a good answer for that) and help the business balance long and short term prospects.
It’s not that things can’t be improved, just that there is so very much low-hanging fruit that has never been implemented at all in a usable manner. We should focus on the huge gains to be made there before the tiny incremental gains to be made by endlessly iterating.
I read thinking to myself "my god, it's just a fucking blog engine, why are you spending so much time rewriting it in shit, realizing what you wrote it in has downsides, and thinking the new shiny wouldn't?".
It's like someone actually believe there's a tech silver bullet just around the horizon, rather than a new way of doing things that eases some burdens and creates others.
You can't actually get all of those things: speed, team size, low defect rate, high performance, high reliability, simplicity, as they are at odds with each other. Generally, the rule is "good, cheap, fast: pick two."
You literally can get more of all the good things in my list by removing unnecessary complexity from a project. And yes, there really are some technologies that, most of the time you see it being used, the entire project would literally be better off with literally nothing in place of it. And yes, people still prefer to use the trendy thing.
I think a potential overarching point that started this thread: Tech should evolve, but it should also stay steady and simple to use. Too much of the "new" stuff is not just a good natural evolution of people solving problems, it's people adding layers of complexity and fluff where there need be none.
I guess it depends on what you're lumping in with "new stuff". I've experience the opposite quite a lot of refusal to acknowledge that a new constraint or condition has modified the parameters of what a solution is trying to solve, dismissed as one off events or something to monitor, then 6 months later when the problem was isolated becoming the new norm, and monkey patches being required because of refusal to acknowledge that the environment has become more complex.
But in my experience companies are full of people thinking there are lots of silver bullets out there. The silver bullet is the new way to do it. The wrong way is the old way to do it.
Related, lots of people jump straight from being 100% naive about performance and architecture to thinking FAANG is the only way to go. They don't stop to think that there are a multitude of midpoints between those two options.
If your business model is to be Facebook or bust it might make sense. But I see a lot of pretty boring and simple businesses resorting to really over-architected solutions. Because the developers are so inexperienced that they think you need eventually consistent distributed microservice soup to serve 10,000 requests per hour.
This so-called evolution is basically creating messes everywhere and code bases that only use one language and one build system are the most understandable ones. Also, once upon a time a programming language was a thing in which you could write anything of your fancy. If that is the case 'multiple programming languages' is itself somewhat of a weird thing.
I don't eschew new technologies. But increasingly I need to see an expected value to justify the uptick in cost.
This does not mean eschewing new technologies, necessarily. Still, it is somewhat like investing in stocks: there may be signs allowing one to tell whether a new trend or stack is likely to go out of fashion soon (which may lead to increased maintenance costs), but it is often safe to assume that the older the tech, the longer it will remain in active use and easy to hire for, making it a sensible recommendation.
Goes without saying that it’s not the only metric, but I find it important, and not applying it at all a violation of customer’s trust.
Software-driven companies with stronger culture (including but not limited to FAANG), on the other hand, have legitimate reasons and resources required to prefer the riskier on average newer stacks—not coincidentally, their teams are frequently at the forefront of developing such tech.
You may already be aware, but this effect has a name:
But as long as statistically the best way to make more money is by job hopping every two or three years, developers are always going to look out for their own resume and best interest.
No job is permanent It is irresponsible not to be focused on keeping yourself marketable.
These recipes are a bunch of bash scripts to glue the toolkit binaries together, all connected via Unix pipes.
With all respect to the authors, I feel that Python would have been a much better choice for this task. Bash is a verbose scripting language to begin with, not to mention much more difficult to modularize. I find it takes me at least twice as long to decipher bash scripts compared with their pythonic equivalent.
I think it's a good example of "old, tried and true" not necessarily being "best".
Bash has been a staple of most Linux distributions for as long as I can remember, but Python only seemed to start being packaged as default in the mid-2000s (or at least, that's the impression I have. My memory could be failing me).
Pretty much anything in bash would be written much the same way in sh, which dates from, when, 1972?
So, no, bash and Python are not the same age, in practice.
Most problems don't need a modern solution, but that isn't an argument against modern solutions for those problems. In the end, it comes down to, which would the group of people writing the code rather have, an old-style solution or a new-style solution? If both are equivalent, there's no reason not to choose the option that looks like it will be the future.
I think the posters you reply to meant exactly such cases.
For the record, I have entirely replaced `grep` with `rg` (ripgrep) in all my workflows. `rg` is newer, written in Rust, and utilises all CPU cores -- unlike `grep`. So I am not against objective and demonstrable progress.
But as another poster replied to you, many of us are against wasting huge amounts of time and effort on very marginal improvements just because the tech is new.
Tell me your tech offers 2x or more speed (or less defects)and I'll use it. But tell me "hey, let's use Kubernetes because.. well.. well... a lot of people use it", and I'll pay zero attention.
Python is an example of a technology that grew relatively slowly and without a hype cycle.
IME hype in this industry correlates pretty strongly with crap.
I remember that comic - I think it coincided not with anything special happening in the python world, it was just when Randall Munroe learned python.
Python benefited enormously by contrast to Perl, despite being slower.
Nowadays, open source development has centralized far more on large public companies, so there's a lot more marketing effort being put on all the languages / frameworks / libraries out there.
Would you suggest that version control (git) is over-kill? You can still use FTP to upload your website.
- Having an accumulator (abacus)
- Accumulator with operations (calculator)
- Multiple registers with more complex operations (early computers with plugboards)
- Stored program computer (abstraction over the plugboards)
- Imperative programming (simple abstraction over operations + registers)
- Procedures, Functions, Structures
- OOP, functional programming, and beyond.
Why do we keep making layers of abstraction? reusability.
We want abstractions that reduce effort by making code reusable.
But abstractions are only a tool, using the tool correctly is on the programmer.
Code is written once, read many times. Languages that focus on "easy to write" are a trap. Languages that focus on "easy to reuse" are what you want.
And on a side note: Never let juniors anywhere near the database design without supervision by the team/seniors. They won't learn anything that way, and they will inevitably make a mess.
I think this holds true in software development teams as well.
When you indoctrinate new developers, you should delegate mentorship to the best* performing teams, so new developers can assimilate good practices and develop an intuition for how thing should work.
I think this is much more valuable than giving them grunt work.
*: just like with genetic algorithms, picking the right fitness function is everything. Good performance is about steady, consistent, sustainable development... rather than trading today's problem with tomorrow's problem.
Reminds me of that time when my company abused Scala Implicits, possible because one of it's libraries for mapping scala to relational database had examples of it.
---
Regarding re-usability. Does that imply well defined interfaces and private scopes? Does that eventually lead us to Pure functions? Afaik, pure func has maybe the highest ease/simplicity for reuse. Happy to be hear your thoughts.
Wouldn't it be the other way around? High interest rates would increase the discount rate for future value?
I believe this is related to our brains being hard-wired to prioritize negative phenomenon and stimuli. Most of those projects shipped and were successful. Users did like using them. However the developers often only saw the bug reports and the endless requests for new features. They never got a chance to talk to users and see how the software was being used and improving the lives of real people. They only see the barb-wire and duct tape.
I had a young developer ask me once about refactoring: how do you get time to refactor your code?
Never. You will never find a person willing to hand you a paycheck to take a month to change absolutely nothing. It gives the business no advantage. But the bugs! the young developer says. To which I say, dear summer child, risk tolerance. The business is willing to take the chance that 1-2% of the time a user may get frustrated, encounter a bug, and file a report or complaint. If the company has to pay you to fix it later that's fine. They can tolerate the cost.
You refactor your code as you go. After you write the code and your tests pass and you think you're done -- refactor first. Abstract away superfluous variables with function application, remove duplicated code, break up long branches with decision tables, etc. Fix that code up before you check it in.
As you get better your refactor steps will be much shorter as you internalize the data structures and patterns that lead you to clean, concise code to begin with.
When you write software commercially you need management that understands how to balance capital, people, and technology. And you need engineers who are pragmatic about their work and the real outcomes: the systems and the people who use them.
That's one of my most valuable self-taught truths! I fought with management and colleagues for years until one day, after a 4-day weekend, it just struck me: nobody can tell me anything when my PR contains both the desired feature (or fix) and the refactoring that slightly improves the status quo of the code.
This was ~5 years ago. From then to today, I hear complaints about my PRs about 2 times a year.
because cleanliness isn't really the goal, the goal is meeting business needs, stability, and discoverability. Often times abstractions create complexity, and that complexity hurts discoverability, it potentially hurts stability, and it can often times be detrimental if business needs change.
So I say abstract when it's clear that you need to, not before.
That's not to say I disagree with the sentiment to get the code working and then go back over it with an eye for cleaning it up, I just dislike the sentiment that this cleanup should be for abstracting things.
The reason for this is that assignment is a common source of errors in imperative programs. We should aim to use as few of them as possible, define them local to their use, and limit their scope.
I'm only talking about small, local refactors that make the code yo wrote easier to understand and maintain.
Refactoring code to introduce new patterns or re-architect a module are better done earlier in the process and much more deliberately, I agree.
But when I try to sell them on the stuff I use personally, the response I get is "it will be too expensive if we have to hire someone for that," yet no thought to the cost-effectiveness of needing to calling a dev on a weekend with overtime pay to fix a null reference that snuck into the codebase during the week somewhere. Or months ago. I'd say another developer is more valuable than clinging to classes of bugs that don't need to exist any longer.
We do what we can but can only do so much to make and keep our code stable, we're a small company with a small dev team and one of the two managers like to meddle in the code. We get by well enough, but despite all the evidence directly in front of them, I am simply not allowed to take the leap into something that would be better in the long run. It just doesn't matter to them.
Another one I get is "that language is too weird," but I've taken to just directly telling them that isn't a criticism and that I need a better reason. Of course it just goes right back to the hiring excuse from above. We aren't hiring and have no plans to hire anytime soon. We're small enough to move quickly, there's no giant organization to migrate into new tooling, none of that, I'm just basically being told that I'm planning too far in advance.
a bit more: https://news.ycombinator.com/item?id=13270271
That part of #4 is so true it hurts. Most of the software I use is full of brokenness and "WTF"s.
About a year ago: AWS Lamba supports Java. Sweet, should be easy. Oh but the command line tools are broken in several ways you won't discover until you try, find they're broken, google around for a while trying to figure out what's wrong, then realize it's not your fault when you find the relevant unfixed issues.
About three years ago: Well I'm writing an Android app so this Google Maps feature should be a piece of cake, I mean, Google makes the OS so surely Maps is amazing on here. Except. Wait. No. That cannot be right. It can't. The Android maps SDK is missing features that the Javascript version has? No. That doesn't make any sense. Oh. Here's a GH repo someone already made to provide a convenient interface from Android Java to the Javascript maps SDK for this exact reason. I mean I guess I don't have to write it myself now but seriously, this was a fucking waste of half my day for no good reason.
A few days ago: Debian installer is flat-out incapable of writing Grub correctly. Several tries, every reasonable combo possible, boot fails with missing OS every time. This ain't my first damn rodeo—something's wrong. Think it's maybe a UEFI issue. Force UEFI. Now my video card doesn't work. Because it's not UEFI compatible? Why dafuq is that even a thing? Open case, reset bios so I have a display again, install again just to be safe, boot to installer's recovery mode, mount, chroot, install grub manually and in precisely the way I'd told the installer to do it the first time, and without changing a damn thing about the config the installer had just written, and it's fine.
This is basically how everything goes every time I try to do anything with software at all. Which is my job. So this is my life.
Software is terrible.
[EDIT] in fact I can think of one area where my tools are consistently as shitty, broken, and unsuitable for their intended purpose as software usually is: it's when I cheap out on power or (especially) hand tools to try to save a buck.
I don't actually hate software, I hate all the shit that gets in between you and the solution to your problems.
Oh.. but nooooo. These monstrosities -- for insane 1980s reasons -- have to update hundreds of thousands[1] of tiny little files and go through some truly insane logic.
The major Windows 10 updates (v1809, v1903, etc...) systematically fail to install on both my PC and my Laptop. I get a BSOD loop on boot, the update retries 3 times and then rolls back.
Now, wait for it: I can do a fresh install with zero issues, with or without an Internet connection on both platforms. I've been able to do a fresh install on both platforms with every version of Windows 10 since the first one back in 2015!
But I can't update a fresh install.
Not ever.
Not with an ISO download.
Not with the manual updater tool.
Not through Windows Update.
Not with any amount of prep work, or special flags, or whatever.
I've updated my UEFI firmware. I tried BIOS emulation. I updated my NIC firmware. I updated my SSD firmware. I tried SATA mode, NVMe mode, and even RAID. For God's sake I updated my TPM chip firmware and you have no idea how fiddly that is. I still have nightmares.
The worst part is trying to unravel the hundreds of megabytes of temporary files, staging areas, log files, diagnostic dumps, and other junk that the update process dumps into wonderfully un-descriptively named folders on my disk.
"Panther" they call it, I assume because it's expected to eat your face. [2]
Amongst the reams of "errors", it eventually complains "fatally" about an unsigned driver being used. I wondered for a while how that's even possible, since Windows 10 x64 no longer allows unsigned drivers. But.. ho-ho... it does, for some user-mode drivers only! And there it lurks! An unsigned driver named "Driver SDK Sample" version "1.0" with default strings in all other fields.
Shit. I've been rooted! Maybe even infected with a persistent root kit. The horror! I work in an IT sector that's targeted by state-sponsored attackers. In a desperate panic I googled and googled until finally I tracked down the mysterious, unnamed, unsigned driver.
It ships with Windows. It's on the f#%$ing ISO, three CAB files deep. It's the Virtual Smart Card user mode driver for TPM-hosted certificates.
Let that sink in: Microsoft ships an unsigned, unnamed driver in their operating system disk image, for the highest-security subsystem they support and then their installer shits itself if it is used in a supported manner. O_o
Okay, fine, I deleted my virtual Smart Cards and I tried to uninstall the offending driver. Except that I can't, because it's unsigned and broken. And the OS won't let me uninstall it anyway, because it's not an optional component and weirdly not "Plug and Play". It took days to scrape this thing out of the system.
It still won't update.
The best I can tell is that the highly popular Samsung SSD 950 Pro is the ultimate source of the incompatibility in my laptop, and the also common gaming motherboard "MSI X99A" is the problem in my PC.
Microsoft only fixes bugs in their installer that the telemetry can report. There's zero quality assurance and unfortunately boot loops log nothing except a common error code, so these bugs will never be fixed.
I look forward to once again being forced to format both of my computers to install Windows 10 v20H1 when it is released soon...
[1] 366,559 files on my system for C:\Windows alone. I counted.
[2] https://knowyourmeme.com/memes/leopards-eating-peoples-faces...
:D
Techies' in contrast are more concerned about building great products. This naturally creates some tension between techies and the business-people. What should be the division of labor, and rewards?