1) It's actually harder to design things that are simple than complex - to take complex requirements, present and anticipated future, and to see the simple design hiding within. This is where you want senior engineers who have built up this expertise over time. As Mark Twain (but originally Blaise Pascal) once said "If I Had More Time, I Would Have Written a Shorter Letter".
2) There is a big tendency nowadays, not entirely bad, to treat projects as systems integration of whatever pre-existing parts can be had, and these parts themselves may bring complexity since they are made for more general use, and also be "impedance mismatched" since they were never designed to work together, therefore requiring glue and adaptors to make them work. Sometimes it's just better to write something suited to the task at hand than try to force something pre-existing to do something it is over-engineerd for, or not entirely suited for.
3) Resume padding. Software engineers like to use the latest greatest packages and techniques that everyone is talking about, and hiring companies are asking for, even if they are not that well suited to the project at hand. Sure, with some effort and extra code you may be able to incorporate some sexy new tech into your project, but it may be to the detriment of the project.
An example being the increased inefficiency, and rate of fuel consumption of aircraft with quadratic air resistance.
But there is an awful lot of complexity in otherwise simple things. Just look at hand tools and see the difference between a power drill and a power driver. And realize that asking which one is simpler is a bit of a red herring. Even better, try and guess which one was created first.
I think, often times, people mistake the results of something from the tools that went into it. Such that it can be tempting to think that simple looking creations were made with simple tools. As often, the opposite is the case. It takes complicated tools to build something that looks simple.
Maybe the argument was that you put more effort and work into what you are building than you do that which you use to build it? I think that is largely fair.
That is actually somewhat in focus when discussing a pen versus the "penzilla." For one, building a pen is a surprisingly difficult thing to do. Especially at scale. For two, people rarely want to have a pen for the sake of owning a pen. Instead, you want to write something.
Yeah, except that a sprinkle becomes a dusting, and then a dusting becomes a coating, and then a coating becomes a clog of dust bunnies, and it's often hard to tell when you need to stop and do it a better way when the business side is pressuring you with deadlines for changes on "what already works".
The whole reason frameworks exist is to _reduce_ the mental backpack by using something that has solved the same problems in the same orderly way.
It's boring common sense but don't take a bromeliad into the desert.
My belief is that all codebases that live long enough will develop this level of complexity with time. The only exceptions imo are where the codebase solves a very particular, fixed problem, e.g. a library for A* pathfinding or whatever. But maybe not even then.
[1] http://johnsalvatier.org/blog/2017/reality-has-a-surprising-...
> Software has a Peter Principle. If a piece of code is comprehensible, someone will extend it, so they can apply it to their own problem. If it’s incomprehensible, they’ll write their own code instead. Code tends to be extended to its level of incomprehensibility.
'We'll fix this later, now just make it work'
It takes more effort to make things simple than to make them complex.
For dim people, like myself. What was the "clear purpose" for Egypt to build giant stone pyramids? Maybe the rest of this will fall into place for me when I understand that.
Imagine reusing an entire physical assembly for only one of its functions (eg a microwave to get a clock) this is the sort of thing we do in software all the time, but would immediately fall apart in other disciplines.
> React piles concepts into your mental backpack: rendering models, hooks, state libraries, routing, and a build pipeline. Say no to it, and suddenly you’re the “neckbeard stuck in the ’90s,” outside the cool-kids club.
Out of the list of the piled concepts, only 'hooks' would be react-specific. The rest are the concepts that a front-end developer will need to think about anyway if he builds a standalone client. If the client is built using non-web-standard languages; or even if static file names need to be stamped with hashes for proper caching, developer has to think of a build pipeline. If the client is decoupled from the server, developer has to think of routing. If things happen on the page in response to user interaction, developer has to think of rendering and of client-side state.
React isn't guilty of any of this. There are plenty of things it is guilty of; but these aren't the ones.
> What? You don’t know how? Okay, instead, sell me this Penzilla - a pen that can erase, write in different colors, play music, dial 911, act as a radio antenna, and even help you cheat on your homework.
Anecdotally, I read somewhere (and agree) that the reasoning behind the "sell me this pen" question is to quickly identify whether someone has the most basic skill necessary to become a decent salesperson: asking questions about need and listening to the answers.
I'm guessing the author of this post does not work in sales (hardly a bad thing) because "selling a pen" by listing all the excellent features of the pen and why it's better than any other pen on the market is exactly, according to the theory, what you should not do.
Do you use pens? What kind of pens do you like? What bothers you about the pen you've got? Well, if this pen doesn't have any of those issues, why not just buy a hundred of them right now and stop wasting mental energy on what pens to buy for the next ten years?
Is it simple though? From my experience, apps written with "sprinkles" tend to become very complex very quickly. Unless the author means something else by "complexity".
To achieve simplicity, you must first outline the complex process, identify commonalities, and then simplify.
You can't reach simplicity without going through and organizing our messy, internal thoughts.
Organizing complexity is the most important skill in software development: https://news.ycombinator.com/item?id=9757892
System design and the cost of architectural complexity: https://news.ycombinator.com/item?id=35470905
Software Complexity Is Killing Us: https://news.ycombinator.com/item?id=16260320
Simplicity is an advantage but sadly complexity sells better: https://news.ycombinator.com/item?id=40266464
Do We Worship Complexity? https://news.ycombinator.com/item?id=18230827
Fighting Complexity in Software Development: https://news.ycombinator.com/item?id=20357203
Complexity fills the space it's given: https://news.ycombinator.com/item?id=40704267
Complexity adds tension.
Bored Software developers add complexity to make their jobs more interesting is my take.
Some complexity in that case is needed, but its aim is to provide a cleaner/simpler access, which is often opinionated, limited to the purpose we have: deployment of development tools for containers.
If you want to experiment, show off as the article implies, start a hobby project.
Edit: removed some fat-fingered typos when I wrote this on a phone
I worked with a front-end developer (React) who needed help integrating with a payment processor. I looked at the docs and hopped on a video call with them to get them unblocked. I ended up having to explain how to POST hidden inputs via an HTML form to them, and their reply was something along the lines of "Oh, HTML is obsolete." They didn't understand the basics because they only new React.
1. We add more functionality to the base of what exists (e.g. HTML). More and more individual features. (e.g. selecting things in the DOM, animations, effects, interactions, tracking state)
2. At some point someone takes all the patterns in the latest wave of functionality and writes a library for them. Library is widely lauded or adopted (see jquery, React).
3. We think of new features building on top what is now the new norm, it's now table stakes. Rinse and repeat.
This is a common pattern in engineering, for example writing new entries to a DB, then at some point going back and compacting.
Right now, "simple" is meant to translate as "good" for the reader and whatever writer wants it to mean. I'm glad, at least, that the article provides an example (React vs plain Javascript). I don't know for sure but I suspect there are at least some valid arguments for using React vs just grabbing dom elements in Javascript.
Changing realities drives complexity, and the more chaotic those changes, the quicker the complexities pile up.
If you look closely at the pyramids, you can see that the later ones were much more solidly built than the former, having learned from past mistakes. But the reality around them hadn't changed (and still hasn't after thousands of years), so every iteration became more and more efficient since they were building anew each time.
Not so with software! Every time you iterate to make something more efficient, every time you're forced to react to a changed reality or imprecise model or failed assumption, it still has to fit into the overall system and keep working somehow. And that could mean working with a system that has a fundamental assumption that doesn't even hold true anymore, and would require so much work to fix the assumption that it's not worth the cost to fix.
The main benefit of software systems is that they can be reprogrammed to deal with changing reality. The downside is that these systems operate on entropy. That's the trade-off.
We like to scoff at old, "crusty" systems and the morons who didn't know what they were doing, but this is the fate of all software. The difference comes from your stewardship over the project, minimizing the impact of the entropy that constantly assaults what you've built. The Linux kernel is a good example.
-- C. A. R. Hoare
The list of accidental complexity sources looks rather short. Off the top of my head, I can think of CV-driven development, of developers not being aware of basic tools, reaching for heavy and marketed ones instead, of awkward regulations pushing to silly solutions, of simple incompetence, of the NIH syndrome (or does that qualify as "creative temptation"?). The "Legacy systems and technical debt" point is applicable to newly developed systems with poor planning and strict deadlines as well. And then there are all the arguments about what is simple and elegant (or not) in the first place.
Something that's complex to the intellect is ill defined. I suspect it can be defined, but it's very highly dimensional. That is there is no scalar complexity number that can be used to compare items directly, and instead you may have two solutions of equal complexity but in different (and otherwise incomparable) axis.
The issue we have today is that we have no academic way to approach complexity so people just sort of develop an intuition for the subsets that they encounter and get bitten by.
However, because they have only a partial picture, they end up simplifying the complexity they do understand in a way that increases the complexity that they do not understand (at least until it's too late for the project).
The difference being that, at least in my side of the technical sandbox, it’s often along the lines of dissuading someone from propping up a K8s cluster for what’s better suited to a single VM, or stop shoehorning multiple overlapping agents onto endpoints instead of properly utilizing what you already paid for elsewhere, or stop carving out exceptions to policies and procedures that make support and maintenance exponentially more complex.
Complexity is a bug, not a feature, at least for 99% of use cases. The problem is that everyone seemingly thinks they’re the 1% that justifies said complexity.
"can anything do everything?"
Meaning, as we invent tools that showcase a novel use, further ideas for how that tool can be used start coming to mind. A nail can hang a picture. If a picture can be hanged on the wall, what else can? Larger wooden shelves can be hanged on the wall if we improve the nail by adding a fastener. Now it's more of a 'mount' than a 'hang.' And so on and so forth.
The overarching question be: "what else could the nail hang, if the nail could hang pictures?" "could it hang everything?"
Of course biologically evolved systems don't occur unless there's some fitness function they satisfy. Well, complex software also provides desired functionality--sometimes the desire is just a result of marketing, but often it's due to real needs.
https://en.wikipedia.org/wiki/The_Mythical_Man-Month
Or if you wan to have more fun read Systemantics
There are hundreds of boutique brands and almost none are making any money. No one sensibly pays msrp you can find bikes 60% off easily.
When you think about productivity , in terms of how much utility can be produced by one person, it’s obviously declining . We have more tools, but the bulk of the effort has gone into getting attention rather than providing utility . Even the product development is more about marketing than utility
In my experience, non-engineers, tend to like simplicity.
I have learned that there's a lot more non-engineers, than engineers. Many of them, have a lot of money, that they are willing to spend on things that are simple.
Working with graphic and interaction designers has taught me to suppress my resistance to making things simpler.
https://www.joelonsoftware.com/2001/04/21/dont-let-architect...
Many businesses are built in such a way that you have little hope of directly contacting your customer, but that doesn't mean you can't try. The desire for complexity often disappears like magic when a developer gets to experience a client expressing happiness over the end results of their "clunky" tech stack.
Putting a late stage "yea I know, but this one time..." hack in, is logistically simpler.
TL;DR we're not addicted to complexity, we're addicted to the abstraction we started with, even when it turns out not to be as good as we thought.
For any topic, you might find a perspective that makes it simple.
But then: For a given topic, a lot of parties each bring their own set of simple requirements.
The patterns emerging as the interferences of these requirements might not be simple.
It's called bat, and it's a great enhancement. I think the author lost me here.
Simple/complex is subjective. Software domain is very diverse that it's unlikely we'd agree on them.
Take mathematicians, for instance. They generally have a shared sense of elegance/beauty. That's the result of a refined intuition from years of study.
Simplicity requires a deliberate planning consideration plus additional effort to maintain, often through refactoring once new requirements surface to implementation. For some people these additional steps are essential to main clear output and a single deliberate path forward. For other people these additional efforts are an impossible chore best offloaded to some third party.
These thoughts about simplicity apply not just to code but to every decision in everyday life.
The truth is that simplicity is difficult to implement and even more difficult to maintain. It's easy to oversimplify, as all you need is to not be aware of some complexity. Given that there's infinite depth to things, it's always going to be easier to be missing information than to have enough. But then simplicity is difficult to maintain. Because each time we touch something the same process happens, causing things to compound. If you're 99% "good enough" (a pretty high and unlikely number) then 10 times and you're at 90%[0]. Often a small mistake can lead to big problems. If things run without much slack, then things break. Entropy is a bitch.
The way I think about it is the inverse of how we problem solve. We solve big problems by breaking them down into small problems. Their composition solves the big problem. Consequently, any big problem is composed of many small problems. So I don't understand why we are so dismissive of the little things. The difficulty is figuring out which little problems meaningfully contribute to big problems and which little problems have little impact or are contributing to a different big problem. So when we use dumb thought terminating cliches like "don't let perfection be the enemy of good" we're ignoring the reality of the issue here. If someone believes perfection exists, yes, fix that. But only really junior people think that. Far more often it is a disagreement about what is "good enough" and so the cliche just prevents having a conversation to figure out what that is. No one is omniscient, so why not hash this out?
I think we gravitate to complexity because simplicity is not simple.
[0] This is oversimplified. I'm intending this for communication rather than specifics. Obviously how things compound matters. The numbers are made up but the math isn't. You'll have to read between the lines to determine the complexity that exists for a given situation. I can't be 100% accurate, so let's work together to communicate as best as we can.
> The simple alternative is just around the corner: sprinkle vanilla JavaScript where it’s needed and don’t build your identity around a framework. That mindset is hard to swallow, though (especially when companies have spent millions convincing developers their stack is the only way forward).
Having grown up doing webdev at its emergence, those were not glorious years.
Even as a solo developer or part of a small team, it was hard as hell to have a perfect mental image of the app at all times, to understand all the combinatorial possibilities of what state your app is in now and what state you want to head to next.
Trying to forever update retained state is hard as hell, full of incredible opportunity for memory leaks, and created some super weird behaviors.
Even more so, "just write the basic code" doesn't scale. It's not a system that an org can follow. Folks will come and go, each going totally different directions. I don't know how to stress how immature and insane this sounds.
But folks love trashing that which is popular. To declare oneself the only sane mind amid a sea of madness.
I really do hope we see some post-React eras dawn, see more, that this isn't it, on and on. But I respect like hell the switch from a retained mode form of webdev to an immediate mode one. It doesn't just skip by so many really bad failure modes, it's often far far faster than the poor incomplete hacked out vanilla.js solution your org ended up with. I want us to change to move to not be stuck here. But to see where we are as unnecessary complexity, to invent fantastic degrading tales about the weak souls of men for getting us here: this is truly the behavior imo of lowlifes, of those spreading propoganda to spread the thinnest false confidence of hatred and disdain against the world.
Things are complex and that's ok. We are learning. The way out in onwards not idolizing a concocted naive pastoralized past.
A few things to note here:
1. Given anything more complex than showing a blog post... eventually the complexity of your homebrew vanilla JS will grow until you re-invent React, but unlike React, your implementation hasn't had millions of users ironing out the kinks over well over a decade.
2. using an industry-standard framework makes developers fungible, and that is why companies push so hard for it. You need to develop something because marketing wants it, at best finished yesterday? Hire a freelancer, as long as you keep your code reasonable they won't have much onboarding time, and your own staff can pick up from there.
And that's not just valid for React, it's valid for a bunch more things. Wordpress comes to my mind first and foremost - yes it's PHP of questionable quality and with loads of legacy garbage, but even in the most remote outback village you'll be able to find some college kid doing wordpress stuff for local businesses as a side hustle. Symfony and Laravel for more complex applications. And for anything Java, there's a reason Spring + Tomcat have grown to where they are, it's just the same.
To convice their managers that only they understand the horrific code they wrote the software in.
Thus because there is no theory, much of software is like art. Just a bunch of arbitrary techniques. That is what OOP is. OOP techniques have no basis in theory or formality yet it masquerades as something formal with big overly complex nomenclature like dependency injection and inversion of control as if any of these techniques mean anything formal.
I digress. Anyway because we don’t have a formal definition of what complexity is we often dont know what direction we are moving in. Is it more complex or less complex? Who knows?
So until someone comes up with a formal definition of what it is we will just be moving in circles.
There are many software products which solve extremely simple problems in very complex ways, sometimes this is called "overengineered". It is what happens, when the simple solution was too boring or when there was a shiny technological hammer and suddenly every problem looked like a nail (think of blockchain products where a simple relational database would have done the trick). This problem exists in hardware as well, but to a much lesser degree, because in hardware every tiny bit you add is cost added to the bill of materials, so hardware engineers have more incentives to keep simple solutions in mind.
To some engineers, them being the only person thar understands the code is a feature, not a bug. That either means they tricked themselves by making the problem appear harder to solve than would be the case (for the own ego), or they tricked others into a co-dependency where the engineer is now needed to understand the solution (for job safety).
One has to admit tho, that some problems are just inherently complex themselves and you have to tackle them at their own level. For example identity managment systems with people from potentially multiple sources where the data shape and quality is out of your control and you still need to reliably create one identity from the data sources. This is a classical: "How hard could it be?"-problem (turns out: very). The solution to that will be complex, because the problems you encounter are. The solution will need to be adaptable because new problems and needs will arise. The solution needs to be maintainable for the same reason. Complex problems + complex requirements = increased complexity in the solution
True mastery in software engineering means the complexity of the solution meets the complexity of the problem, while delivering in all kind of other dimensions like maintainability, legibility, adaptability, security, safety, reliability, ruggedness in changing OS-environments, ease of use, etc.
Many software engineers you will encounter are still in their "write and forget"-stage of their career. They never had to face The Sysamdin that had to deal with their flaming piece of crap software falling apart with every second system update. They have next to no admin experience themselves, that would tell them that good software chugs along for decades in a changing environment.
The problem with complexity in software engineering is that we can just add it. No beancounter breaths down our neck if we add an extra dependency. The problems arising from added complexity are intangible until they aren't, and then it is often too late.
P.S.: I smell chatGPT in some of the phrasing like: "Complexity shouts, “Look at me!”, while simplicity whispers “Did you notice?”."
If there was one reason people gravitate towards complexity this author is talking about, it's probably because they want to see if they can do it. In some contexts it's annoying, but it's also what moves the needle from time to time.
Your 1-10 person team probably does not to use the same tech facebook or google are using, most of the time.
I'm not a very clever person, and I keep things pretty simple, so when I explain something to someone, they can generally get a grip on it pretty quickly.
To them it's been such a small jump they think, that person doesn't deserve much of a reward, heck I could have done it.
Whereas when someone talks about the complexity, people think, wow, there's no way that I could have done that, let's pay that person LOTS to keep them
Most of the time, if I'm working in blender for example, I want some really sane prepopulated shader values and one size fits all rig values for sofas vs chairs, but sometimes I want to go crazy and make chairs out of glass and slime, etc.
But simplicity also requieres a lot of effort. Complexity is a side effect of laziness and not putting effort in. Common in corporate programming.
The desires of certain character types culminate in leadership. Those with this character type who have actual visions that fit withing the symbiotic nature of our reality were about as wanted among their peers as alphas were wanted in human tribes where betas felt treated unfairly and thus ganged up on alphas and their offspring, then establishing fraudulent hierarchies alienated from individual competence, which was compensated by collectively established complexity that served to maintain and uphold the fraudulent hierarchies.
Over time, in IT, engineering and science, this lead to narrower and narrower fields of possibilities, aka probabilities that certain behavioral locks and refused directions and angles will be unlocked (after emerging).
Business psychology, marketing, sales, and culture and psychology are entangled and "envelop" instead of developing. It appears like an evolution but it's an alienation, a contiguous/continuous self-imposed, self-reinforcing isolation from and within a symbiotic, open system.
The complexity forces the reduction of productive points of friction in order to create atomic points of contact with the parent system that minimize even productive and constructive influence. This then enforces rules of self-preservation instead and dictates dogmas of engagement with the rest of the world.
It's the obfuscation of the oldest Ponzi scheme which prefers isolation in singularity rather than a symbiotic evolution. The first who makes it to the patent office vs FOSS. Factory farming for a fancier dinner table. Who cares how much is thrown away, how much energy is wasted and how any of that impacts the chemical cycles of a symbiotic system that kept optimizing for exactly that for billions of years--by design, via self-organization, not necessarily as a hard-coded yield. The world wide web feels similar, btw.
Again, it's a WIP. (I just whipped those paragraphs up, but there's an imaginary pin board with a lot of sticky notes ...)
I know this sounds all very "old man yells at cloud". What can I say. Grug dev only telling fireside stories learned from bitter experience chasing shiny rock.
Job. Security.
You see, if only you knows how it works, how could they get rid of you? /s (obviously /s)