Dr. Dobb's Calls BS On Obsession With Simple Code
theodp writes "Over at Dr. Dobb's, Editor-in-Chief Andrew Binstock has a nice rant on The Misplaced Obsession with Simplicity. 'Any idiot can write complex code,' goes the old maxim, 'the true art is writing simple code.' Right, Andrew? Wrong (mostly). Binstock explains, 'It's not true that any idiot can write complex code. Complex code is difficult, often very difficult, to write. It's entirely true that it's more difficult to maintain, too. But that's the nature of complexity. Some things are intensely difficult to express in code and they require complexity, simply because they're not inherently simple.' After citing the complex-but-necessarily-so code of Al Aho and sometimes-misguided reverence for cyclomatic complexity limits to help make his point, Binstock concludes, 'My view of simplicity is unemotional and free of idolatry because I define it with respect to complexity, rather than the other way around: Simplicity is the quality of code that is no more complex than required to express the underlying complexity. In this way, simple code can be intensely complex. There is no inherent good/bad dichotomy.'"
Everything should be made as simple as possible, but not simpler.
Interesting article, but this seems an issue of a very pedantic interpretation of a common idiom.
When I (or I suspect most) whine about pointlessly complex code, it's just that. Code that is more complex than is reasonable for the problem. No one expects a simple solution for a challanging problem. It's an overly complex solution to a simple problem which we complain about...
The way I heard it was "Everything should be made as simple as possible, but no simpler." However I have since learned that me be a paraphrase of the actual quote, "It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience."
It is really very simple. If you write complex code to solve a problem, someone else solves with simple code, you have just shown your inferiority WRT the other engineer.
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
Hoorah!
In databases things get normalised down to their most basic elements, which is neccessary and good. In coding, everything might individually be simple, but the whole might be horrendously complex. Good documentation makes almost anything simple though, and by that I mean docs written intentionally to explain the overall codebase rather than disconnected sections.
Your code shouldn't be more complex than it really needs to be. But isn't that the way we thought about simple code all the time?
Computer simulation made easy -- LibGeoDecomp
I have often noticed that complexity is added to code when it grows over time. Typically, a project starts off very well. We have requirements and we use the best possible design with limited future expansion capabilities and come up with simple code that works well. However, over time, things change and we come across situations that the original code cannot handle. But instead of writing from scratch, we hack it and that is how complexity and subsequently bugs get added. In my experience, the base infrastructure code for any system always looks simplistic and beautiful. The ugly part is often how it has been used over the years.
The is a good reason I need a separate class defined to output each character in the string "Hello World!"
I only look human.
My mother is a halfling and my dad is an ogre, so that makes me an Ogreling
Why do we simplify expressions in algebra? Because ink is expensive? Because it takes too much time to write a lot of letters? Or because calculations are very hard to understand when they take up entire pages when they could be simplified to a few letters?
Writing code Simple or Complex really depends on the Developer and the mindset of the developer at the time.
Sometimes the Simple Code actually makes it too hard to manage. Say you are given specs and you find it fits nicely in a mathematical function. So you create that function and it works fine, until a new change happens then you function is just wrong and you need to redo it. However if you make your code a bit more complicated, that change might be just a simple if statements, and you are all set again.
The line depends on the skill of the developer. Having worked with recent grads who really did write good code, however lacked experience, got really frustrated at my designs because they accounted for "changes that wasn't in the specs". Why are you using a String instead of an Int, the int is faster and takes up less space, the data told us this element is a number. However my experience told me for that case you could come across a state where it could be a string. Months later there was an Oh By the Way We have this case which made it a string, and we didn't have to remap a bunch of fields. Experience is key.
If something is so important that you feel the need to post it on the internet... It probably isn't that important.
You know what's bad?
An object with a single 2200 line method that takes 70 parameters
You know what's also bad?
300 tightly coupled classes that have no individual use.
Striking the balance is what is really important and there's no one size fits all metric for that beyond peer review.
I find myself cringing every time someone comes in and makes a grand sweeping statement about simplicity or density or whatever else because it ignores problems by carpet bombing a philosophy.
Cyclomatic complexity doesn't mean much without analysis.
Not my code. As long as the data doesn't have to be turing-complete I'm satisfied.
Any idiot can write complex code.
Bzzt, wrong. It's:
Any idiot can write complicated code.
"Simplicity is the ultimate sophistication."
-- Leonardo da Vinci
"Plurality should not be assumed without necessity."
-- William of Ockham, often referred to as Ockham's Razor -- the simplest explanation is usually the right one.
"Everything should be made as simple as possible, but not simpler."
-- Attributed to Einstein
"If you can't explain it to a six year old, you don't understand it yourself."
-- Albert Einstein (attributed)
"Truth is ever to be found in the simplicity, and not in the multiplicity and confusion of things." -- Issac Newton
"Beauty of style and harmony and grace and good rhythm depend on simplicity."
-- Plato
"The greatest ideas are the simplest."
-- William Golding, Lord of the Flies
"Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage to move in the opposite direction."
-- E.F. Schumacher
"Those guys are all wrong."
-- Andrew Binstock, Editor in Chief, Dr. Dobbs
Choose well, reader...
#fuckbeta #iamslashdot #dicemustdie
Frankly, I was a little disappointed in this article. His arguments seems a bit - for lack of a better term: simple.
Is there anyone out there who is arguing that simple solutions to inherently complex problems exist and are a good thing?
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Keep on knockin'
https://robbiecrash.me
I didn't see any good examples in his article. The only example he had was a switch statement with 35 cases being simplified by using a table which somehow makes it harder to read than scrolling through a 35 case switch statement. I'm not convinced at all. This guy sounds like he could benefit from reading Clean Code by Robert C. Martin.
The Official Site of 1337 Pwnage
Simplicity is word that gets batted around a lot. When it used to mean "the shortest distance to a solution to the immediate problem", you are often trading immediate simplicity for longer term inflexibility.
I've found the simplest solutions are those which are well designed, which take into account not just the immediate problem at hand, but reasonable future variations of that problem. The up front investment in thought and design and pay off in a big way down the road when new problems can be solved more elegantly, quickly, and be more maintainable.
Its like someone who collects books. You could just stack them up on the floor, but finding one or adding more is going to increase the chance that they all fall over. If you take the time to get some bookshelves and think of a cataloging system, your book collecting is going to scale much better.
Good design and good structure benefit simplicity. If you ignore it, you are just pushing complexity into the future.
I see this a lot with the various "on rails" development schemes, where they sweep a tremendous amount of complexity under the rug so users can quickly develop whatever they want. Only later they discover that something is broken or slow with their project and now fixing it requires a herculean effort because they never really understood what was happening before. It's discouraging and many projects just resign themselves to being broken or start to incorporate ugly workarounds to try to avoid the problem without really fixing it.
I read the internet for the articles.
I limit it to 1's and 0's
The world is made by those who show up for the job.
...to his writing, too. Or, as Antoine de Saint-Exupéry has put it: "A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
Computer simulation made easy -- LibGeoDecomp
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
-Brian Kernighan
When you redefine your opposition's argument and then knock it down with your own argument it is called a strawman. That's what he just did there.
No one is saying in regards to simplicity that all programs should be two line bits of nothing.
What people are instead saying is that code should be efficient, tight, and achieve the end goal as simply and directly as possible.
What we are and have always been talking about is efficiency. It goes back to the first computers that had very limited memory. They required VERY efficient code because they simply didn't have the storage or memory to run anything that took up more space. As a result, code for those machines tended to be very very efficient. It was a requirement.
When we complain about complexity, we are not complaining that the task of the program is too complex. Rather, we're complaining that the program is badly coded. We are complaining that it is inefficient and disorganized.
So nice try. Try again.
I've decided to stop wasting my time responding to AC trolls/sockpuppets... so if you want a response from me... login.
If you write some code and you can't explain what it does, without reading comments or external documentation, then it was written in a way should be simplified.
Complex, simple, OOA/D, functional, good coders, bad coders, sloppy code, hacked code, elegant code, modular code.
Coding is truly an art much like producing fine wine.
And like fine wine, no one gives a damn. It's freaking alcohol... not grape juice...
In conclusion, code just needs to damn work for the given purpose and be maintainable for the target skill level to maintain it. That's it, who cares about complex vs simple. Much like fine wine, as long as it's alcohol no one really cares on the making part.
I'm afraid software developers will read this article and use it as a lame excuse to write complex code, because it's easier to write complex code than to write simple code, though it's much, much harder to maintain, enhance, and debug complex code.
Complex code hides bugs. Complex code is generally less robust and reliable. Complex code usually has more security holes.
Sure, some things have to be complex. But generally, you should strive for small functions (methods) that do one thing, and do it well, and keep side effects as localized as possible.
And the same applies up the stack. Make sure each layer (methods -> objects -> programs -> etc.) alone can be grokked inside the head of a single person. This is how you manage complexity. This is how you build big systems.
Brooks made a big point in "No Silver Bullet" about the difference between what he called accidental complexity (introduced by the developers) and essential complexity (introduced by the reality of the problem). And the key thing is that the accidental complexity needs to be avoided or fixed with tools, but the essential complexity can't be avoided.
I am officially gone from
Use bright, talented programmers to get the initial job done, throw "simple" code across the ocean to $3/hr code monkeys in India.
Dr. Dobb's Journal's motto was once "Running light without overbyte." Looks like this valuable maxim is now beyond their ability.
Sometimes it's a good choice to use more complex code when it provides a substantial speed increase. Sometimes it's good to slap something together just so it will run. But if there's no substantial advantage to code that isn't simple, simple is best.
Contribute to civilization: ari.aynrand.org/donate
Black is White. Freedom is slavery. Simplicity is bad. Complexity is good. Binstock is +1 Funny.
When all you have is a hammer, every problem starts to look like a thumb.
The article is mildly entertaining (especially for the awk bits), but the ending is plain stupid, i.e. flat and inane beyond belief ;-)
I don't think that a sane person would explain the apparent improvement of newish cars reliability by the increasing number of built-in programmable gadgets with their millions of code lines. If anything, there is an optimum beyond which the cars will start failing in new and spectacular ways...
"I had incorporated some sophisticated regular expression pattern-matching.."
So many simple projects turn the corner of complexity, and never look back, right about at that statement.
Join the Slashcott! Feb 10 thru Feb 17!
A lot of what makes code ugly and complex is working around bugs and incomplete features in languages, database, etc. Every time I start a new project I try to start with a good clean framework. If never fails that you hit a point where documented features dont work and after waisting many hours of research you find the ugly hack workarounds. These acheive the end result but make you cringe when you maintain the code.
"Readability and change-ability by future maintainers" should be the primary goal. Obtaining that goal doesn't necessarily lead to the most simplest (smallest) code.
However, it's often a difficult goal to codify (describe precisely) because human psychology and physiology are still half-science-half-art subjects. And, every individual is different and thinks and sees better under different circumstances compared to other individuals.
It's best to get multiple opinions on different styles to try to find a consensus.
This reminds me of a debate on the readability of a sample Lisp case-like and IF-like statement set versus the VB equivalent of a given application. To me the VB version just looked easier to read than the Lisp version despite Lisp being smaller in the test, partly because VB forces certain line-spacing and repetitious keyword conventions on you. It looked closer to how one may document an algorithm on paper for quickest visual absorption. You lose some compactness because of that, but a consistent and familiar "product" can improve visual identification of the parts.
The Lisp fan claimed that "one will eventually get used to" the Lisp approach and it would grow easier to read for anybody who tried long enough, not just him. I'm a bit skeptical of that claim, plus my future replacement may not have that experience and be starting from scratch reading Lisp.
The Algol-style block constructs (as found in VB, C, ADA, etc.) are deeply ingrained in most developers. Even if it was possible to "get used to" Lisp's approach, the pool of experienced Lisp developers may have to reach a certain size threshold in order to make replacement staffing viable for a typical company.
The Algol style has been time-tested, and very few tech companies have gotten rich from Lisp despite being popular with graduates. The pudding doesn't favor Lisp yet.
(C's case/switch statement really needs an overhaul, BTW, at least for derivative languages of C where machine speed is a secondary concern.)
Table-ized A.I.
KISS is not "make it simple". KISS is "keep it as simple as possible while retaining clarity, but not simpler". It is about not adding complexity _unless_ needed. Anybody competent understands that. This "rant" is entirely redundant and shows a lack of understanding of fundamental engineering principles.
Most ACs are not even worth the keystrokes to insult them. Be generically insulted by this and ignored otherwise.
The problem is there isn't a way to determine from a simplistic line of code metric whether or no a line is truly needed, resulting in sloppy bloated code.
Every line of code which is properly designed out of a block of code is a line which will not have to be executed, debugged, stored or every worried about again:
http://folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt
Sphinx of black quartz, judge my vow.
You're the guy who puts all those dictionaries in the code with strings as keys. I hate you.
captcha: damage
I've had to debug systems where code was abstracted so much - to make such simple routines that it was nearly impossible to debug. So, though simplification helps - sometimes writing a long routine maybe preferable.
My view of simplicity is unemotional and free of idolatry
Calling your opponents 'idolaters' is the opposite of unemotional. It is an emotionally charged indication that you don't actually understand the other viewpoint.
"First they came for the slanderers and i said nothing."
In journalism school I had a professor who had personally interviewed the Dalai Lama and as a result he often had a very practical outlook on things. When he gave us our first writing assignment (an obituary for a famous person of our choice who was still alive... I decided William Safire had died of a heart attack upon learning that genetic testing proved Hillary Clinton was not, in fact, a congenital liar), someone immediately asked how many column inches he wanted. He replied with a question: "How long is a man's arm?" People started trying to measure their arms against things or guesstimate the average length of a man's arm, asking if that meant he wanted 30 column inches. Finally he quieted everyone and said, "A man's arm is long enough to get the job done. No more. No less." Likewise, the articles we were to write were to be long enough to get the job done. No important things left out, no filler added in. It was an important lesson in judgment.
I think the same applies to code. It should be just complex enough to get the job done. No more, no less. Sometimes that means you're going to have complex code, but it shouldn't be any more complex than it needs to be.
Even the source he cites admits that complex code is a bitch to maintain.
You claim to be a brilliant programmer, yet don't give me an elegant solution to an interesting problem. That's truly the set of problems -- ego, elegance, and interest. Most of us are writing software that's boring, aren't truly in the small brilliant fraction, and the problesm we are addressing are uninteresting.
The only "example" he brings is one of awk where the matching module by Aho was labelled as unmaintainable by other programmers. Then basically Binstock states "Aho is a superb programmer, so the module must have been written as simple as possible". What rubbish. It's like stating that a great pianist will find the best fingerings for a piece he plays well, and you just need to write them down.
The actual truth is that a great pianists will find fingerings intuitively that suit their skill set and style of playing. But that does not mean that most of them are fit for writing down, publishing and teaching to others.
Good fingerings are matched to the problem space, not to the performer space. And good code matches the problem space to the tool space, the used language and libraries.
The article does not get any of this. It just harps about "complex problems exist, so complex code is fine". The truth is that the concepts underlying complex code can usually be expressed in an understandable manner: read "The Art of Computer Programming" for a lot of examples. And transferring the structure and transparency of a good human-readable description to code without large losses is an art requiring lots of diligence and a thorough grasp of the language and its patterns, and how they match the problem patterns.
Hacking code from the ground up is pretty much the opposite. And particularly hard-core programmers who can read core dumps, back traces, assembly and so on dive into the mind frame of the machine rather than the abstract representation of the problem in human-understandable terms. They need discipline to pattern their code along the lines of the principles of the solution.
And I should know. I learnt coding when the output was made available hours after your input (and that includes compilation errors), possibly with a core dump. I soldered my first computer together myself. When I bought my first disk drive, I had to write bootstrap loader and BIOS (in assembly language, of course) before being able to boot first time.
This brings me to the point that is truly the heart of the matter: It's not simplicity that matters, but readability. Can the code be understood with the least amount of effort given its inherent complexity? That is the true criterion. How readable, or if you prefer, how maintainable is the code with respect to its complexity?
"First they came for the slanderers and i said nothing."
The problem is not that the complex code is "bad", but that there are many stupid developers using pretty much complex libraries and modules, and don't forget the copy/paste methodology, and the result is something that is "somehow" working, and extremely complex and hard to read. Well written and maintained code is always pleasure to read, no matter its complexity or the used libraries. One more thing, give an idiot a hammer, and every problem he face would look to him like a nail.
This quote from TFA seems to argue *against* complexity:
"I had incorporated some sophisticated regular expression pattern-matching technology into AWK Brian Kernighan once took a look at the pattern-matching module that I had written and his only addition was putting a comment, 'Abandon all hope, ye who enter here.' As a consequence, neither Kernighan nor Weinberger would touch that part of the code. I was the one who always had to make the bug fixes to that module" (from Masterminds of Programming, p. 103). Complex problems require complex code.
So he wrote some code that was so complicated that no one besides himself is able maintain it. That sounds like more of an argument *against* complicated code than for it.
Note that it's not Al Aho that said "Complex problems require complex code". Is awk still using the same code today, or has it been rewritten to be more maintainable?
Be wary of people who fill code with too many buzzword concepts in fake preparation for a fake future. It's often just job security in disguise.
Most "patterns" meant to add flexibility often introduce other change hindrances: it's rarely a free lunch and they are merely gambling on a certain pattern of change. If you hard-wire change handlers for the wrong kind of change, ones that go against the "grain of the wood" of the actual future, it's worse than having a simpler design to begin with.
Whatever, input and output may very well be strings as they can be from different character sets for example. Internally a number is a number. Formatting should be done with the input or output only(even within the program itself), in your case handled by the individual state for that case only. You fail. You don't change your entire paradigm because of "someday" scenarios.
Compare .NET code to the compiled machine code. .net runtime is nothing but a set of functions in a separate file. using simple functions means main()can be an outline of the program, for example .
... 1000 more lines
Which is easier to understand and work on? The
By any measure, Linus Torvalds is an incredibly successful programmer. His guideline is 6-8 lines per function or so.
Consider these two example programs:
Stand
Turn left
Walk four steps
Turn right
Walk two steps
Turn right
Vs:
heatlunch()
readslashdot()
Even if the function heatlunch() is used nowhere else, using it makes the program far more understandable than inlining the walking code to get to the microwave.
Make everything as simple as possible, but not simpler.
I take that to mean that you don't want an undue complexity in your model, but your solution will be as equally complex as the problem you are trying to solve. If you take software system that is complex enough to warrant OOP style classes, interfaces, etc. and you instead decide to write "simple" code and do it all in one big-assed function, you have in fact made the solution more complex, or you are missing key elements that should be supported.
Simplicity is always natural and it never shows any extra humour and emotion.
http://www.Kaffesmagen.dk
I totally agree with the assertion that some things are inherently complex.
But it's not bad to place "simplicity" out there as a goal anyway, because programmers in general tend to create overly complex solutions, so anything that makes them think a little and reign in that tendency is a good thing.
Thinking along those lines can help act as a check to premature optimizations which often add complexity that is not needed.
"There is more worth loving than we have strength to love." - Brian Jay Stanley
If you want to talk to a "digital computer", ultimately, your code has to be translated into on/off (1, 0) pulses. Therefore, the simpler, the better. Unless the author of this article has another type of computer that can understand more complex states than on/off, his entire treatise is bunk.
I know there used to be analog computers, and quantum computing might have states other than on/off, I can't speak for these systems. However, the more common digital computer is what I am referencing.
If telephones are outlawed, then only outlaws will have telephones.
I have seen a few very simple lines of code that are an absolute nightmare to maintain, all because there was very little commenting or documentation as to what the code was responsible for doing. Whether the code is butt-simple or extremely complex, the key to understanding it is the documentation.
Even very complex problems can be made to look simple at various levels of abstraction. Hiding complexity inside objects that represent real-world objects is a good way to make the code that uses those objects simpler.
In development, plan to do at least one major refactoring after the project is feature-complete to move complicatons in and out of abstractions, add new abstractions or collapse old old ones as needed to make things "feel good".
If nobody else can understand the stuff you wrote, then you have created a problem and it's up to you to solve it. If you are prepared to do that, then fine. Be a slave to your code for the rest of your career.
However, if you want to write code and move on then you can act professionally and create product that others can take off you and use as your legacy. it can still be complex - just so long as you can explain in the documentation why it is complex and what the (complex) functions actually do. You never know: those who follow might even learn something valuable from your output - rather than learning not to go anywhere near your stuff in the future.
politicians are like babies' nappies: they should both be changed regularly and for the same reasons
Probably the licensing...
“He’s not deformed, he’s just drunk!”
Sometimes you can't avoid complexity but if unavoidable abstract the complex stuff and put it behind a bunch of facades or something. If it works, then nobody has to go back there, i.e. developers how aren't as skilled or don't like complexity. ;)
I liken this to an overflowing garbage can. Every subsequent coder delicately places his code on top of the steaming pile, praying that it all holds together.
Then someone makes one too many changes. The pile topples, and the poor sod who touched it last is the one who has to take the garbage out (rewrite it).
Last post!
Captain Obvious to the rescue
accurately define good according to a criteria and seek it out.
But ... but ... what about "first 10% of coding effort give 90% of the functionality"? (Or 20/80% split, as per Pareto principle in general).
:/
I've been living in a lie
These arguments all sound kinda silly, much like underscore_naming(), preferred in unix, vs StudlyCase as seen in win32 world and various corporate programming shops (java..).
...is probably complex as hell.
But I bet there is very little spaghetti in that massive and complex code base.
I am very small, utmostly microscopic.
I have spent nearly a decade refactoring 5 of the worst codebases out there. This guy is full of shit. Go back to whitepapers, dummy. Make it seem more than it is so the customers are impressed over nothing.
Is the code elegant? Does it fulfill its requirements while maintaining flexibility and maintenance abilities? Does it take advantage of existing objects?
I don't care if it's 10 lines or 1,000 as long as it's elegant. Clever programming is not elegant - it's generally a hack because someone wants to show how much more they know than everyone else. Spaghetti string code is not elegant - it's lazy.
That's part of writing good code. Make it elegant. Make it something that when the next person opens it up you can't hear the frustrated groan from across the room.
That's my opinion and how I try to write my code.
Maybe I'm out of the loop, but I didn't realize there was an obsession with simple code. I've been saying for years that code should be as simple as possible and as complex as necessary. I didn't realize this wasn't already common sense and that I could get an article published about it. Honestly, if your code is simpler than it should be it probably isn't getting the job done. And who wants code that is more complex than it needs to be? OK, I've definitely had some co-workers who seem to go out of their way to make their code as complex as possible, but I've been hoping that they are the exceptions.
I was just reading this article and I stopped at this paragraph, unable to understand it:
"Standing Accretion Shock Instability," or SASI. This term expresses the fact that the initial sphericity of the supernova shock wave is spontaneously broken, because the shock develops large-amplitude, pulsating asymmetries by the oscillatory growth of initially small, random seed perturbations."
http://www.sciencedaily.com/releases/2013/06/130627083034.htm
No clue if that could be expressed in a more simpler form.
Of course you have no choice but to deal with no less than the complexity that is required by the needs of the business problems you're trying to solve.
What I and many others object to is the ridiculous over-complexity that is added to an application just to serve the Ego of the Lead Designer. For example, I worked for a company where this dickwad lead went crazy essentially built his own application-server environment. In so doing, he massaged his ego but made life miserable for anyone who had to work on and maintain this piece of tripe. The first day I started working for the company he crowed about how he had made all these hard choices to have sub-500ms response times. After that initial conversation, I and everyone else who worked there understood what a joke that goal was. The over-complex design meant that the app barely met 10x that benchmark. I never heard another mention of the sub-500ms response times. It was and is a total joke. So, the application was a pile of spaghetti, with none of the usual tools you have at your disposal. The same guy had a dozen annoying OCD habits that just made him a nightmare to deal with. The application itself was full of whack a mole bugs and only happy-path coding that made it take weeks to solve a bug that should have taken a day or two.
The complexity that I and many others object to is UNNECESSARY, EGO-STROKING complexity, such as using Hibernate when there are only 6 tables in the database, or using iBATIS for the tiniest app.
In the Java space, one of the only bits of complexity that earns its keep is the Spring stack--but if you hadn't noticed, the dominance of the Spring Framework stems from its insistence on reducing complexity, getting rid of checked exceptions and needless boilerplate.
Another kind of needless complexity is pulling in a brand-new technology and all its problems, version conflicts and breakages when you're only using 5% of its capabilities, such as pulling in MongoDB when you really don't need it and are not using it for any big datasets.
EgoChumps like Mr Chips are a nightmare to work with. A nightmare.
This is the heart of Binstock's reasoning from TFA, with some of the more insightful parts bolded to make it easier to follow along.
If you didn't like TFA, please help me understand where he gets it wrong...
begin excerpt:
There's a big difference between poorly written code and complexity.
Unfortunately, parts of the Agile movement have tended to obfuscate the distinction.
A rule of thumb I've seen cited several times is that functions with a cyclomatic complexity number (CCN) of more than 30 or 35 must be rewritten.
This is patent nonsense and implies that all complex code is equivalent to badly written code.
Moreover, there's a peripheral problem with the assertion; namely, that every branch of a switch statement adds 1 to the CCN.
So, if your switch has 35 branches, you violate the threshold with no reasonable way to simplify your code.
(Sure, you could use some kind of table instead of the switch, but now you've taken logic that was easy to read and made it considerably more difficult to follow.)
Parent post:
No, I think you misunderstand his argument. Some people create metrics to determine a program's "complexity", then judge programs on an absolute scale based on that metric.
This argument is saying that those metrics are bullshit because they don't take into account the difficulty of the problem at hand.
dom
Suffix trees and suffix arrays make for a brilliant study of elusive simplicity.
Suffix array
The paper includes a 50 line reference implementation (excluding comments).
Why wasn't this algorithm discovered thirty years ago?
It's not like people didn't recognize this algorithm is an important building block since way back. Thirty six years to arrive at "rather simple". Amazing.
Yeah, and one more thing: Slashdot has been around for sixteen years and still can't render diacritics pasted in from Wikipedia. Who could have anticipated we'd wish to use those? Besides, it's a good American tradition. Right after being awestruck by the Statue of Liberty, Karkkainen steps off the boat and declares his name to the port authority.
Karkkainen? What kind of name is that? Umlaut schmoomlaut. You can have Kirkby or Kirklen. Kirlen it is then. What's that? I missed a K? Whatever, no point starting over. Next!
So the meta data indicated to convert strings to ints otherwise they meant to be used as a code or something.
Sounds like you got lucky, those assumptions could come back to bite you. It's best to confirm with the domain expert, never assume!
One thing about code though, is that's it's often more re-usable than an essay or an article.
In some cases, you might favour writing a function/module/etc that's slightly more complex but able to service more scenarios. That allows the code to be more useful in the future, either in anticipation of growth in the current project or for use in future projects.
I didn't read the article, so your mileage may vary, but I have been programming since I was around 7 or 8 years old and I just turned 38.
Here goes. The vast majority of code that you will need to write and maintain does simple things. It should be simple and expressive so the next person can both fix your mistakes and add new behavior.
Every once in a long while you will be given something fairly complex to do, and as you gain experience you learn to isolate that complex piece, perhaps write tests and drivers, special debugging code for it, documentation and wiki entries, and otherwise treat that code specially so it doesn't become a burden.
Under 1% of code does tricky things. It is true that you will find non-trivial code in academic papers, maybe something like a cryptography research paper. Eventually that code will become something like openssl. But 99% of what you write will be simple database, GUI, or text processing work, or something else fairly mundane. That code is arguably much more important. The cryptography routine won't need much maintenance but GUI and database requirements change all the time.
If you find yourself always writing mind-numbingly difficult code, perhaps you need to relax a little bit, because you won't make it 30 years.
In short, it's good to make your code as simple and elegant as you can for the particular situation, while keeping it readable and maintainable -- which, ironically, in some instances may require more complex code, just so the solution is detailed enough to be understandable. Of course, no one wants to plague of "clever" solutions that are so read-only as to be unmaintainable. Simple as you can, complex as you need.
Q: What's wrong with complexity?
A: It hides bugs!!
Notwithstanding that some tasks are inherently complicated and there's just no simple way to express it I would posit that the problem with unnecessary complexity is that it hides bugs.
Bugs hide in the edges. They swarm in corners. They positively thrive in interfaces.
Simple (i.e. clean) code helps make the bugs stick out.
There is some business case or need behind each programming effort. That case/need has an underlying language, a grammar, that embodies what needs to be done and when and how. The challenge in software development is to find programming constructs which, inasmuch as is possible, clearly expresses the problem's solution.
Through hard-won experience we've discovered things that suggest where bugs like to hide; what are sometimes called "Code Smells." Massive, nested IF statements. GOTO statements. Global variables. Side effects.
But, these are only symptomatic. There are times when some of these ARE necessary to achieve maximum performance. In other words, not all cases are bad, but they suggest a long, hard look to ensure they are necessary.
Consider programming languages. We started with machine code. Then we wrote assemblers to make it easier to express what we wanted to do. Then came macros and functions. Still later we developed higher level languages. All of these steps allowed us to more easily express what we were trying to do.
Consider this continuum. Case 1: A single program with thousands of lines of code and no functions or subroutines. Case 2: The same application implemented with thousands of functions, each of which contain at most 5 lines of code.
There's probably a sweet spot in between those extremes. A point where the abstractions of what needs to be done closely mimics the problem domain. Where the inputs and outputs are clearly delineated and checked. Where each function is the "right size". As the lowest level functions are implemented and tested, they provide a framework, a language in which one can more easily express what is being done. It is clear what is attempted and how. And it is clear when things are amiss. It makes the bugs "stick out."
When we fail to do this, when we unnecessarily complicate the code, then problems arise. We struggle to grok the code. In this struggle, overwhelmed in trying to follow the "good" paths, we fail to see all its shortcomings. We provide hiding places for bugs. They blend in. They avoid observation. Or, when detected, resist eradication. For some samples, take a look here.
tl;dr. Given: Some problems are just plain complicated and defy any further simplification. Fine. Other problems are amenable to consistent abstractions. When we fail to do that, we introduce unnecessary complexity. We breed bugs.
I work on highly-available systems (telecom equipment, core network stuff). Even there, some parts of the system can be less robust and some parts need to be as robust as possible.
The design for a given component needs to take into account how robust that component needs to be. Do you check EVERY POSSIBLE error condition and figure out intelligent ways to handle them (can be quite difficult and very time-consuming) or can you just panic the system if you detect something has gone wrong and you don't know how to handle it?
In some cases, you need to trade off between reliability and performance. In other cases you need to ship a product so it goes out with known corner cases that aren't handled because in the real world that condition should never happen.
While I'm generally on the check-for-errors case, I find that I generally don't have the time to test for every single documented error code and handle each one differently. I usually test for a few that I know I can deal with, and then bail out with loud log messages if the others happen.
Something as simple as open() can spit out something like 22 separate errors. I generally don't check for each one separately.
There already exists a word for "no more complex than required", and that term is ELEGANT.
Its been around since the beginning of programming. Get with the program. This is a non-story.
GCS/MU/P d- s:- a-- C++++$ UL++ P+ L++ E+ W++ N o K- w--- O M+ V- PS+++ PE Y+ PGP t+ 5- X R++ tv+ b++ DI++ D++ G+ e++ h-
In my 10+ years of experience in the field, I have learned and come to appreciate that it's important to strive for clean code. Simplicity is often a side effect, but you can model vastly complex concepts still in a clean way. To me, therein lies the art.
Occam's razor (also written as Ockham's razor from William of Ockham, and in Latin lex parsimoniae) is a principle of parsimony, economy, or succinctness used in logic and problem-solving. It states that among competing hypotheses, the hypothesis with the fewest assumptions should be selected. In other words, the simplest explanation is usually the correct one.
Apply recursively to the created solution.
I guess there is a minimum level of complexity which can be achieved for a given task. You can make things unnecessary complicated and that is wrong. However, you cannot make complicated task (infinitely) simple. I experienced that trying to simplify my project and rewriting until I noticed I cannot simplify it anymore and it just has to be that complicated and built as an improvement on previous effort.
Amazing one can reach the /. "frontpage" these days by writing something this trivial (and having a big name). All TFA says is:
- The complexity of a complex problem cannot be reduced indefinitely.
- Code should strive to be as simple as possible but cannot be made to violate this law.
I'd think anyone who has ever written complex code (like most science/engineering code, or a 3D game engine) should knows this from experience. Not to mention people with basic background in information theory and half a brain cell. If you're a programmer and you think "wow, that's a clever insight", then better get another job.
And this is where the supposed seasoned programmer shows his true bias and ignorance beyond measure to ensure that he's labeled a poseur for all time. To ignore any good or bad part of code is to exhalt bullshit programming practices.
And you people listen to this ill-educated half-assed programmer of a fuck, why?
This and exactly this. I have worked on quite a few systems in my life, and not once I have though "only if this system was more complex". Most of the time what I found was duplication, unnecessary abstraction layers, no separation of concerns, too much unnecessary flexibility, very roundabout and complex solutions to very simple problems. Usually I am able to refactor it into something that is ~5x smaller, and easier to understand, and faster, and easier to change.
I hate it when people add flexibility and features in advance, and it ends up never used. And while Agile approaches seem a bit cowboyish sometimes, I agree with them on one point- implement the simple stupid solution first, make it more complex only when necessary.
--Coder
Then it's a relatively few lines of code to do regex matching.
In the real world, plan to never be able to come back and refactor your code until the next feature that touches it.
Sorry, but gas mileage has not sored due to well written, but complex code. It has gotten of the ground [sored my ass] due to forced regulations. The Department of Energy asked every major auto manufacture in 1990 to be part of a DoE Engine efficiency project where everyone must submit a 90mpg automobile. They all did it. Not a single one exists on the market to this day. How come? They weren't forced to release them. They didn't reach improved Carnot engine cycles because of some embedded system: they used different composite materials in the engine block allowing doubling and more heat to burn the fuel more efficiently. End of story.
It's morons like him that highlight the difference between programmers & software engineers - programmers require adult supervision.
As long as software is coded like a wirewrap prototype, software folks will (rightly) get no respect.
Good code is complex in the background but looks simple when viewing through different lenses
I have been a software developer for about 30 years. I have written a lot of code and maintained a lot of code written by others.
I have found that when I understand a problem I can reduce the complexity of the code I write; one measure being number of lines.
I have read other people's code and been amazed by the simplicity possible when solving a complex problem.
I have also gotten headaches from reading code that is very complex that doesn't need to be. Often such code came from self-educated software developers.
Based on these experiences I came up with a maxim: The complexity of a solution is inversely proportional to the understanding of the person who created it. In other words, the better a person understands the problem to be solved the simpler the solution will be. That doesn't mean that a solution is simple, but it does mean that it is understandable. I have yet to encounter a situation, whether it be software, or organizational issues, or pretty much anything that people can do, to which this maxim does not apply.
Another measure is can the developer explain the code? I have had developers tell me that I will never be able to understand the code they have written and then made no attempt to explain the code. All that communicates to me is that they do not understand what they wrote.
Pretty easy to create complex code, hard as hell to maintain it.
Comment removed based on user account deletion
Complicated code isn't complex code. Complex code is natural. In the realm of complexity, one can write complicate code or simple code.
"... the ratio of function to conceptual complexity is the ultimate test of system design. Neither function alone nor simplicity alone defines a good design."
It's obfuscated or clear. I strive every day to write the clearest code possible, whether it's complicated or not depends on the problem I'm trying to solve.
"Dude, pounds are so metric, fuck that." - Noah
when broken into small parts as isolate from each other as reasonable.
A car is complex, but you don't design it as one thing. You design each piece individually to be ut together withing a defined method for the vehicle.
The Kruger Dunning explains most post on
" Often such code came from self-educated software developers."
think that's a bias, but I would love to see an actual study .
The most overly complex code I have ever seen have been from MIT and Cal-Tech.
The worst code I have ever scenes has been from self taught 'web masters' Worst in that they clearly didn't understand basic concepts of software.
The Kruger Dunning explains most post on
Has he also forgotton the original subtitle of the mag, "running light without overbyte"?
mark
Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it.
It is indeed true that some problems are necessarily complex in code. Sometimes very complex. But I have seen so many examples of code that took much simpler problems and made them very complex. Sometimes just as an exercise in using all of the complexities of a language's features. I think this is what distinguishes the really good software developers from those that are not so good.
Simple code is harder to write, because it is hard to define. I dont know of any filter to put code into and get back a value on "the simplicity scale". That said, some code is easier to follow (read) and does not contain unnecessary variables and routines. In general, I would say that the shortest amount of code to accomplish the intended goal is the simplest... but there is a limit to this. One code may be easier to debug and reproduce errors and output important values during execution.
When most programmers and debuggers look at 'complex' code... they are usually talking about the format and choice of loops and iterations. Or that the code has been upgraded and modified so many times, that the style no longer flows in a natural and readable way.
In summary: simple code takes longer to produce because it all needs to follow a single style and it needs to be created with a mindset for future developers who will be upgrading and debugging the code. And the total logical flow of the program needs to be considered in order to reduce and remove useless iterations. It is easier and faster to modify existing code without these considerations. The resulting code of fast upgrades without consideration for future changes is what programmers sometimes call: spagetti code. It is spagetti code that I would suggest is what most programmers think of when they call some code "complex".