This write-up is too light to provide any real insight. In particular, how do you assess simplicity?
From an example I'm currently working through on a hobby project... do I use a RS-485 transceiver with a custom line code, or do I use a 10base-T1 PHY? Ethernet, especially one pair ethernet, is undoubtedly more /complex/, with echo cancellation, a complicated line code, etc; but if I use the PHY, then /I own/ that complexity.
(For pure software folks, the equivalent question is internal implementation vs external dependencies. Do you implement a 1D barcode yourself, or do you import a third-party dependency for QR code reading?)
The problem is that answering this depends not on some objective notion of simplicity, but on a realistic assessment of /where time will go/ during the development process. If development time dominates, then exporting complexity is a win. But if testing time dominates, and since exported complexity still needs to be fully understood during testing, then in-house simplicity wins.
And which of these cases dominates is very much a project-by-project and team-by-team decision.
,,Complex comes from the Latin complecti, which means “to entwine around, to embrace''
Simplicity requires layering, so in your examples the main requirement for simplicity is about how intertwined your hobby project is with the transciever code or ethernet code.
As long as the abstraction layer works well for you without getting too much into the details of the implementation, it's a simple solution.
Of course it's not a clear answer whether you should do things yourself or use a third-party, but if the third-party works perfectly for use case without significant tradeoff in your system, of course it's better to use it.
The problem is that answering this depends not on some objective notion of simplicity, but on a realistic assessment of /where time will go/ during the development process.
I don't think anyone mentions time as a proxy for simplicity. At least, the article certainly doesn't. You're right that the author doesn't objectively define simplicity, but I don't think anyone can. What is simple tends to be different to different people/teams, based on skills, tools, etc., available.
I know what's simple to me. I know it may not be simple to you. I know what's simple for a team in my org and I know it may not be simple for another team in another org. But, I do know what skills someone in my position and in my org is expected to have, and I know what tools are available to us, so I can make some real assertions here about what is "simple". Get worried beyond that, and you get bogged down on unknown unknowns.
I agree, the article is entirely focused on semantics. In the real world, outside of research and education, no one ever attempts to make something more complicated than it needs to be. A software project consists of thousands of different problems with solutions that must be mutually compatible through a web of compromises. You have known hard requirements, known soft requirements, known future requirements, unknown future requirements, and you're searching for the simplest possible solutions for each of them that result in something like a "minimum net complexity." The problem of "over-engineering" comes when a solution that optimized the simplicity for one concern becomes incompatible with another concern. It's inevitable in any system where requirements are subject to change over time.
Does simplicity equal time? In my mind it doesn't. As for your example I'm a software person and bringing external dependencies feels like adding layers of complexity. Simplicity is minimalist, if I need an external dependency I generally try to extract the actual part I need and understand it and have it my own code to streamline what I need. From my view external dependencies are the epitome of complexity.
Comparative simplicity requires you to accurately imagine the entire lifecycle of each alternative.
This is a lot of work. And your prediction can end up wrong anyway (by your mistake or by the world changing).
How are we then to make choices? Perhaps just, if one solution seems clearly simpler (to you), then choose that. If one looks unnecessarily complex, don't choose that.
Simpl-est derails us perfectionist programmers. So maybe "Do the simpler thing that can possibly work"
"You don't need to know a man's weight to know that he's fat" - Benjamin Graham.
EDIT "Could possibly work" also implies a lack of foreknowledge as to its actual simplicity, or whether it will function correctly... or at all.
I like to distinguish complexity from complication: the former requires cleverness to understand more of; the latter time and effort.
In the simple case of a solo project, as much complexity as you understand is fine; in a team you obviously need some idea of a threshold, not that you could quantitatively define it. Complexity isn't necessary, though isn't a problem - complication on the other hand is always bad, it's just making things hard to reason about, but may be necessary if the only alternative is adding unacceptable complexity.
The problem with discussing 'simplicity' is that it's an antonym for both complexity and complicatedness.
Simple is a matter of intuition, and that can't be transmitted to others easily, or with a single class or book.
At one particular job we got punished by the business for calling things 'easy' when what we mean is that we understand the problem and all of the steps are (mostly) known. Our boss coached the hell out of us to say 'straightforward' when we meant 'understood', instead of using 'easy' as an antonym for 'quagmire' or 'scary'.
> the equivalent question is internal implementation vs external dependencies.
Liabilities. Take the Windows EULA, its a contract that states MS is not liable for anything, standard software contracts state the same, so if boils down to being able to prove negligence, which can be sued for.
For example, do you trust the suppliers? IF they are in a different country, what's the chance of legal recourse if negligence can be proved, knowing about political interference if the entity is valuable enough?
So yes I agree, how do you assess simplicity, and as Billy Gates would say... it 's complicated!
Simple isn't the same as easy, and it isn't always obvious where the complexity is. One should beware of "simple" solutions that either hide the complexity, or shove it someplace else. The skill is to identify and minimize unnecessary complexity, which is another way of phrasing "Do The Simplest Thing That Can Possibly Work".
Thanks for this, it's great. I've never explained it as clearly as these two do, but this has always been my philosophy and what I try to aim for when developing software. I find that a lot of times people opt for easy, thinking that it's simple, but down the road they find out it is actually complex. I wonder if we will every see a real shift to focusing on simplicity and the gains that come from it?
I wish I could convince product teams that the MVP is often just a single feature. Like a search bar + results page.
Something we can ship very fast, then we can add the banners, tracking for marketing, account creation, user ratings, community forums, results commenting and sharing, image carousels and a mobile app with push notifications that the results changed. You know, the regular MVP stuff.
So many people think agile means waterfall using sprints.
My voice is hoarse from saying this so many times. It's a constant battle trying to explain that it's not perfect, but we can't improve on it based on feedback, if it's not done.
Multics was a huge produce that failed (initially). Bell Labs washed their hands of it, and didn't want anything to do with Operating Systems again.
Ken Thompson wrote an initial scrappy version of Unix in 3 weeks. Re-writing to C was a tremendous move because it meant that Unix could be ported easily to many other systems.
I heard someone say that the genius of Dennis Ritchie was that he knew how to get 90% of the solution using only 10% of the work.
I'm working my way through Unix Haters Handbook [1], and it's a good read, even for someone like myself who really likes Unix.
Unix and C are the ultimate computer viruses
-- Lawrence Krubner
I thought c was primarily developed for the initial purpose of being the language used to write Unix and that their developments were practically one after the other and that Ritchie and Thompson were colleagues at Bell? C was designed for portability in mind?
As a relatively newbie software developer, I'm going to ignore this advice and just try to cobble together something that works and I'm deliberately not going to worry about whether or not there is a simpler, cleaner solution to the problem. The rationale is, if I keep searching for the simpler cleaner solution I'll keep falling down rabbit holes and never get to the point of having a solution to the problem at hand. After the fact, if someone comes along and says, 'hey, here's a simpler solution' that's great, but if I don't at least have a working project, nobody will even bother to deliver that helpful input.
> As a relatively newbie software developer, I'm going to ignore this advice
As a relatively senior software developer, I'd say don't worry about it too much. The article accepts that reducing complexity is hard, and it's ok if you can't make it any simpler. Try not to add intentional complexity when you can, because statistically speaking, YAGNI.
This industry is full of clowns trying to upsell things that nobody needs, just don't fall for it.
Then launch that MVP into production, and never be given an ounce of time by your PM to fix any of the shortcomings that you thought were not part of "Do the Simplest Thing". Iterate on that principle for new features, too: what's the simplest way to get this new feature out? And this one?
And then find yourself surrounded by tech debt an a system that was cobbled together, not designed.
This is a very common case, sadly. But this is due to people failing to use MVPs correctly. Instead of being a tool for the sole purpose of rapid learning and iteration, it is used to falsely accelerate delivery.
When done well, you build a series of prototypes/MVPs with the sole purpose of learning faster what customers really need. You should then put all your effort into building that really, really, well, and kill off anything that didn't work out.
Ideally, you should always have new, minimalist code for new features you are exploring, and lots of old, extremely well designed, implemented and well-tested code for all the areas you already know are critical for your users - and nothing in between (no "nice to have" features, no failed experiments that linger on and contribute to your tech debt...)
This takes a ton of discipline, but in my experience the only alternatives are to either build up a ton of tech debt, or build things extremely well from day 1, only to end up dying due to low velocity (even if you get some critical decisions spot on in the beginning, no PM or engineering team that I've ever seen has been able to make only good decisions over several years...).
I think “simplest” needs to be applied to the whole system, not just to the change at hand. If you keep the system overall as simple as what could possibly work overall, you’re probably already reducing tech debt. Tech debt usually implies that things are getting unnecessarily complicated (accidental vs. essential complexity).
If this is applied to programming, then just be aware that "doing the simplest thing that can possibly work" integrated over time typically won't result in anything good. For any given task, the simplest thing that can possibly work will often have other effects that are hard to quantify on the spot (like increased tech debt).
If you're working on things that are intended to be short lived, then just do whatever is needed to get the job done and move on. If you're working with something where you know there's a good chance it'll be around for some time, then every once in a while, someone will have to take on the role of saying "no, we're not gonna do the simplest possible thing right now".
Maybe. But it's often a lot easier to get from having something simple and working to something more complex and also working than it is to spend the whole time with nothing working until the complex part is completed.
Don’t draw diagrams? Seems like not using a very valuable tool. Diagrams help you think and thinking can save you time in building the wrong thing or the wrong way. The diagram shouldn’t take ages and pencil/paper is fine.
The sentiment is nice but ceases to be useful when people have trouble distinguishing what could possibly work from what appears to work for a bit and then breaks down horribly.
And it's not really about the fallibility of people. Often in engineering you can be designing in a space with a lot of unknowns, that simply can't be resolved without building out a bit to explore the space more. In such case some level of future proofing is warranted.
I'm kind of suspicious of adages like these that assume perfect information.
I always look at adages like these as something to keep in mind for the future. We can choose the simplest thing now and make it easy to swap it out for the more correct and more time-consuming thing later.
Sometimes the difficulty in distinguishing what the simplest thing could be comes from being in a group setting where people have equal say in the matter.
I think everyone has personal anecdotes to support the idea of doing the simplest thing suitable for that moment. But how to convince the group? I'm not sure, I don't always succeed.
A situation where I did do just the simplest thing is when I was asked to use project management software and a build server for a very early stage project with only myself as a developer. I declined.
Instead I made a script to compile and package everything and emailed that to the others. We used an instant messenger for communication. It worked great for the early stage when the focus is on the MVP, though the project didn't go anywhere due to business reasons.
It will always still be possible to use the project management software and build server later. But it wasn't necessary at the very start.
This is effectively meaningless (and the article even recognises that) because it delegates all meaning to the definition of "works".
Even "passes all the tests" isn't a great definition. What are you testing?
For example think about build systems. "Works" could be "builds everything correctly" in which case the simplest thing is just a shell script with all the commands written out.
That's obviously terrible, so then "works" becomes "doesn't unnecessarily repeat work" and you end up with Make.
But then Make doesn't scale to large monorepos with CI so then "works" becomes "and doesn't allow undeclared dependencies" and you come up with Bazel.
So the same meaningless advice can justify wildly different solutions.
I think better advice is just "try to keep things simple where possible". It's vague because it requires experience and design skill.
I feel like this advice works really well in some places and really poorly in others.
I think those using safe languages and broad frameworks have a much greater ability to execute on "keep it simple" than those who use something like C and build 100% of their code in-house.
addaon|3 years ago
From an example I'm currently working through on a hobby project... do I use a RS-485 transceiver with a custom line code, or do I use a 10base-T1 PHY? Ethernet, especially one pair ethernet, is undoubtedly more /complex/, with echo cancellation, a complicated line code, etc; but if I use the PHY, then /I own/ that complexity.
(For pure software folks, the equivalent question is internal implementation vs external dependencies. Do you implement a 1D barcode yourself, or do you import a third-party dependency for QR code reading?)
The problem is that answering this depends not on some objective notion of simplicity, but on a realistic assessment of /where time will go/ during the development process. If development time dominates, then exporting complexity is a win. But if testing time dominates, and since exported complexity still needs to be fully understood during testing, then in-house simplicity wins.
And which of these cases dominates is very much a project-by-project and team-by-team decision.
xiphias2|3 years ago
,,Complex comes from the Latin complecti, which means “to entwine around, to embrace''
Simplicity requires layering, so in your examples the main requirement for simplicity is about how intertwined your hobby project is with the transciever code or ethernet code.
As long as the abstraction layer works well for you without getting too much into the details of the implementation, it's a simple solution.
Of course it's not a clear answer whether you should do things yourself or use a third-party, but if the third-party works perfectly for use case without significant tradeoff in your system, of course it's better to use it.
majkinetor|3 years ago
dfxm12|3 years ago
I don't think anyone mentions time as a proxy for simplicity. At least, the article certainly doesn't. You're right that the author doesn't objectively define simplicity, but I don't think anyone can. What is simple tends to be different to different people/teams, based on skills, tools, etc., available.
I know what's simple to me. I know it may not be simple to you. I know what's simple for a team in my org and I know it may not be simple for another team in another org. But, I do know what skills someone in my position and in my org is expected to have, and I know what tools are available to us, so I can make some real assertions here about what is "simple". Get worried beyond that, and you get bogged down on unknown unknowns.
kokanee|3 years ago
unknown|3 years ago
[deleted]
hattmall|3 years ago
hyperthesis|3 years ago
This is a lot of work. And your prediction can end up wrong anyway (by your mistake or by the world changing).
How are we then to make choices? Perhaps just, if one solution seems clearly simpler (to you), then choose that. If one looks unnecessarily complex, don't choose that.
Simpl-est derails us perfectionist programmers. So maybe "Do the simpler thing that can possibly work"
"You don't need to know a man's weight to know that he's fat" - Benjamin Graham.
EDIT "Could possibly work" also implies a lack of foreknowledge as to its actual simplicity, or whether it will function correctly... or at all.
OJFord|3 years ago
In the simple case of a solo project, as much complexity as you understand is fine; in a team you obviously need some idea of a threshold, not that you could quantitatively define it. Complexity isn't necessary, though isn't a problem - complication on the other hand is always bad, it's just making things hard to reason about, but may be necessary if the only alternative is adding unacceptable complexity.
The problem with discussing 'simplicity' is that it's an antonym for both complexity and complicatedness.
csdvrx|3 years ago
BurningFrog|3 years ago
Yeah, it'll be a project-by-project and team-by-team decision, and that's as it should be.
GoblinSlayer|3 years ago
EGreg|3 years ago
hinkley|3 years ago
https://www.youtube.com/watch?v=SxdOUGdseq4
Simple is a matter of intuition, and that can't be transmitted to others easily, or with a single class or book.
At one particular job we got punished by the business for calling things 'easy' when what we mean is that we understand the problem and all of the steps are (mostly) known. Our boss coached the hell out of us to say 'straightforward' when we meant 'understood', instead of using 'easy' as an antonym for 'quagmire' or 'scary'.
moremetadata|3 years ago
Liabilities. Take the Windows EULA, its a contract that states MS is not liable for anything, standard software contracts state the same, so if boils down to being able to prove negligence, which can be sued for.
For example, do you trust the suppliers? IF they are in a different country, what's the chance of legal recourse if negligence can be proved, knowing about political interference if the entity is valuable enough?
So yes I agree, how do you assess simplicity, and as Billy Gates would say... it 's complicated!
loudmax|3 years ago
Simple isn't the same as easy, and it isn't always obvious where the complexity is. One should beware of "simple" solutions that either hide the complexity, or shove it someplace else. The skill is to identify and minimize unnecessary complexity, which is another way of phrasing "Do The Simplest Thing That Can Possibly Work".
mattbuilds|3 years ago
hummus_bae|3 years ago
[deleted]
Xeoncross|3 years ago
Something we can ship very fast, then we can add the banners, tracking for marketing, account creation, user ratings, community forums, results commenting and sharing, image carousels and a mobile app with push notifications that the results changed. You know, the regular MVP stuff.
So many people think agile means waterfall using sprints.
kemiller2002|3 years ago
blippage|3 years ago
The greatest example of this is Unix.
Multics was a huge produce that failed (initially). Bell Labs washed their hands of it, and didn't want anything to do with Operating Systems again.
Ken Thompson wrote an initial scrappy version of Unix in 3 weeks. Re-writing to C was a tremendous move because it meant that Unix could be ported easily to many other systems.
I heard someone say that the genius of Dennis Ritchie was that he knew how to get 90% of the solution using only 10% of the work.
I'm working my way through Unix Haters Handbook [1], and it's a good read, even for someone like myself who really likes Unix.
Unix and C are the ultimate computer viruses -- Lawrence Krubner
[1] https://web.mit.edu/~simsong/www/ugh.pdf
7speter|3 years ago
photochemsyn|3 years ago
selcuka|3 years ago
As a relatively senior software developer, I'd say don't worry about it too much. The article accepts that reducing complexity is hard, and it's ok if you can't make it any simpler. Try not to add intentional complexity when you can, because statistically speaking, YAGNI.
This industry is full of clowns trying to upsell things that nobody needs, just don't fall for it.
zamnos|3 years ago
[deleted]
deathanatos|3 years ago
And then find yourself surrounded by tech debt an a system that was cobbled together, not designed.
int0x2e|3 years ago
This takes a ton of discipline, but in my experience the only alternatives are to either build up a ton of tech debt, or build things extremely well from day 1, only to end up dying due to low velocity (even if you get some critical decisions spot on in the beginning, no PM or engineering team that I've ever seen has been able to make only good decisions over several years...).
layer8|3 years ago
gopisuvanam|3 years ago
LAC-Tech|3 years ago
A lot of software lacks a clear plan. A big patchwork of local maxima commits that won't get you where you need to go.
So I say go ahead and draw some pretty pictures. What's the overall vision here?
vinkelhake|3 years ago
If you're working on things that are intended to be short lived, then just do whatever is needed to get the job done and move on. If you're working with something where you know there's a good chance it'll be around for some time, then every once in a while, someone will have to take on the role of saying "no, we're not gonna do the simplest possible thing right now".
VBprogrammer|3 years ago
layer8|3 years ago
unknown|3 years ago
[deleted]
quickthrower2|3 years ago
harpiaharpyja|3 years ago
And it's not really about the fallibility of people. Often in engineering you can be designing in a space with a lot of unknowns, that simply can't be resolved without building out a bit to explore the space more. In such case some level of future proofing is warranted.
I'm kind of suspicious of adages like these that assume perfect information.
TacoSteemers|3 years ago
Sometimes the difficulty in distinguishing what the simplest thing could be comes from being in a group setting where people have equal say in the matter.
I think everyone has personal anecdotes to support the idea of doing the simplest thing suitable for that moment. But how to convince the group? I'm not sure, I don't always succeed.
A situation where I did do just the simplest thing is when I was asked to use project management software and a build server for a very early stage project with only myself as a developer. I declined. Instead I made a script to compile and package everything and emailed that to the others. We used an instant messenger for communication. It worked great for the early stage when the focus is on the MVP, though the project didn't go anywhere due to business reasons.
It will always still be possible to use the project management software and build server later. But it wasn't necessary at the very start.
NegativeLatency|3 years ago
I do think that many people make the wrong tradeoff in terms of complexity to features ratio though.
IshKebab|3 years ago
IshKebab|3 years ago
Even "passes all the tests" isn't a great definition. What are you testing?
For example think about build systems. "Works" could be "builds everything correctly" in which case the simplest thing is just a shell script with all the commands written out.
That's obviously terrible, so then "works" becomes "doesn't unnecessarily repeat work" and you end up with Make.
But then Make doesn't scale to large monorepos with CI so then "works" becomes "and doesn't allow undeclared dependencies" and you come up with Bazel.
So the same meaningless advice can justify wildly different solutions.
I think better advice is just "try to keep things simple where possible". It's vague because it requires experience and design skill.
readthenotes1|3 years ago
It is far more active than the imperative version.
One might say the interrogative is the simplest thing that could possibly work...
irrational|3 years ago
bob1029|3 years ago
I think those using safe languages and broad frameworks have a much greater ability to execute on "keep it simple" than those who use something like C and build 100% of their code in-house.
mynameishere|3 years ago
https://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.ht...
"XP" almost, but not quite, became a real cult.
TacoSteemers|3 years ago
But it is a nice counter to some people's decisions to go for overly complex or risky (unproven?) technologies or designs.
buescher|3 years ago
tpoacher|3 years ago
So, grain of salt, and all that.
yarg|3 years ago
Othertimes do simplest thing that will most simplify similar tasks in the future.
joebuffalope|3 years ago
Keep It Simple Stupid