Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×
Programming Software

Dr. Dobb's Calls BS On Obsession With Simple Code 381

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.'"
This discussion has been archived. No new comments can be posted.

Dr. Dobb's Calls BS On Obsession With Simple Code

Comments Filter:
  • To quote Einstein (Score:5, Insightful)

    by BenSchuarmer ( 922752 ) on Thursday June 27, 2013 @01:05PM (#44123497)
    Everything should be made as simple as possible, but not simpler.
  • Meh (Score:5, Insightful)

    by Anrego ( 830717 ) * on Thursday June 27, 2013 @01:07PM (#44123541)

    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...

  • by parallel_prankster ( 1455313 ) on Thursday June 27, 2013 @01:12PM (#44123599)
    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.
  • by Anonymous Coward on Thursday June 27, 2013 @01:14PM (#44123647)

    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.

  • Premise is wrong. (Score:2, Insightful)

    by Anonymous Coward on Thursday June 27, 2013 @01:15PM (#44123657)

    Any idiot can write complex code.

    Bzzt, wrong. It's:

    Any idiot can write complicated code.

  • by girlintraining ( 1395911 ) on Thursday June 27, 2013 @01:17PM (#44123671)

    "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...

  • Re:Meh (Score:2, Insightful)

    by Anonymous Coward on Thursday June 27, 2013 @01:17PM (#44123677)

    I think Dr. Dobb's stopped being relevant oh like 10 years ago. Its like a total kids magazine now, nothing like it was years ago. Most articles in it are unreadable.

  • by lgw ( 121541 ) on Thursday June 27, 2013 @01:24PM (#44123773) Journal

    Arguing against stupid "complexity metrics" is fair. A programmers job is to game the system. Give him a metric other than making the customer happy, and it will not end well.

    But I've seen far too much code that was simply far more complex than it needed to be. Stop tripling the size of your code for use-cases that no one has asked for, people!

    If you can make assumptions that significantly simplify your code, and those assumptions fit within the actual, stated requirements of the work (ignoring requirements that exist only in your head), for goodness sake make those assumptions.

  • by dkleinsc ( 563838 ) on Thursday June 27, 2013 @01:33PM (#44123889) Homepage

    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.

  • by internerdj ( 1319281 ) on Thursday June 27, 2013 @01:36PM (#44123925)
    Not all customers are smart enough to know to ask for everything. Even a smart customer may not be able to give you a real answer for what happens in X cornercase. Presumably you (or someone like you) are being paid to hash out all the hidden requirements and assumptions to achieve the customer-stated requirements.
  • by Hentes ( 2461350 ) on Thursday June 27, 2013 @01:46PM (#44124043)

    Complex problems are defined as problems with no simple solution. The article is not just simple, it's a tautology.

  • by raymorris ( 2726007 ) on Thursday June 27, 2013 @02:03PM (#44124255) Journal
    Compare .NET code to the compiled machine code.
    Which is easier to understand and work on? The .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 .

    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 ... 1000 more lines

    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.
  • by Zalbik ( 308903 ) on Thursday June 27, 2013 @02:06PM (#44124293)

    Presumably you (or someone like you) are being paid to hash out all the hidden requirements and assumptions to achieve the customer-stated requirements.

    Yes, but this should be done prior to code writing.

    Far too often I've seen extremely complicated code designed to handle "what-if" scenarios that never happen.

    i.e.
    Developer: "I wrote that configuration module in case they ever need to change the parameters of X"

    Me: "Did you ask if X would ever need to be reconfigured?"

    Developer: "Of course! And the client said that sure, if I could make it configurable, go ahead and do so"

    Me: "And did you ask how likely it would be that X would need reconfiguration? Or under what circumstances X would need to be reconfigured? Or what types of 'reconfigurations' they think they would need? We're looking at 2 man-months of code, plus testing, plus implementation time here....was any kind of cost-benefit analysis done to see whether it was worth it to write this?"

    Developer: [blank stare]

  • by gstoddart ( 321705 ) on Thursday June 27, 2013 @02:17PM (#44124415) Homepage

    Stop tripling the size of your code for use-cases that no one has asked for, people!

    So, we should stop doing any bounds and input checking if the client didn't ask for it explicitly?

    Is this part of Agile Programming or something? Write the most incomplete code you can get away with because it isn't in the spec?

    I once had a co-worker bitch and complain I was checking the result of every single function, including strprintf() -- he said it was unnecessary. Not long thereafter, we spent some time tracking down a problem which turned out to be in his code, because he wasn't checking anything (again, because it was 'unnecessary').

    If you write shitty, incomplete code up front, it's much harder to make it less shitty and incomplete later. If I know from experience there's a bunch of things that can go wrong, I'm going to try to account for as many of those things as possible when I write it.

    Those use-cases nobody asked for can sometimes be the difference between code which collapses at the first unusual inputs, and stuff which can at least tell you WTF went wrong. Because sometimes, even the simplest of things can fail.

  • by spiffmastercow ( 1001386 ) on Thursday June 27, 2013 @02:17PM (#44124417)

    Compare .NET code to the compiled machine code. Which is easier to understand and work on? The .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 . 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 ... 1000 more lines 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.

    But you forget you also have to walk back to your desk.. At that point, you have two usages of a pathing algorithm.. Which means you're repeating code, which means that using a function to enable code re-use instead makes sense. I'm hardly an advocate for complex functions (most of my code are 1 or 2 liners), but there are times when you simply cannot express something concisely in a short function, and the answer to that is *not* to artificially reduce it into code that does nothing but resides in a different location.

  • Re:Meh (Score:5, Insightful)

    by T.E.D. ( 34228 ) on Thursday June 27, 2013 @02:22PM (#44124475)

    Do you re-use your functions, or do they only exist to break apart a single operation into smaller blocks? If it's the latter, then he may have a good point

    I disagree, strongly. Breaking a large routine into smaller ones abstracts away what those smaller routines are doing. It puts a boundry around their interaction with the rest of the code, and puts their code away somewhere that I don't have to worry about, unless there's some reason I want/need to know the details of how that routine accomplishes what it does.

    If you put it all flat into one big routine, I have to read and grok everything in that routine, if only to reassure myself that none of it has interactions with the one area I care about.

    We actually have terms for this stuff: Cohesion and Coupling [wikipedia.org]. Cohesion in particular is an important concept here.

    I find it amusing that the author's big example is Aho's parsers. Parsers are one of those special cases, as lexical analysis is a problem that is generally best solved by state-machines. I've tried for years, and really there aren't a lot of good ways to code lexer state machines that aren't either way slower than the typcial implementations, or a web of control flow that looks like a huge mess to those of us reared on structured programming. It isn't talked about much, but lexers (and some parsers) unashamedly make use of goto statements as their core braching mechanisim. Using Aho's awk parsing code as an example of why "clean" code isn't always desirable is like using the US Marines as an example of why killing people is often a good option for solving disputes. Perhaps its true in a technical sense, but its really crappy advice to be giving the general public.

  • by Anonymous Coward on Thursday June 27, 2013 @02:24PM (#44124489)

    Clearly, not taking his own advice here...

    Dude, the man ushered in a revolution in physics. His idea of simple would melt most people's brains.

  • by DahGhostfacedFiddlah ( 470393 ) on Thursday June 27, 2013 @02:32PM (#44124581)

    On the other hand, even if code isn't used in more than one place, that doesn't mean it's not "expressing something concisely".

    Additionally:
    1) Methods are great ways of naming orthogonal snippets of code, rather than using a comment that may become obsolete.
    2) Breaking large methods into smaller ones increases maintainability by enforcing certain constraints such as not reusing variables declared 100 lines up just because they happen to serve similar purposes.

    I agree that you don't want to just arbitrarily break your method up for the sake of smaller methods, but I don't think reuse is necessarily the best way to judge whether methods should be refactored.

  • by ZahrGnosis ( 66741 ) on Thursday June 27, 2013 @02:45PM (#44124725) Homepage

    I think you're confusing feature-creep with a comment that was meant to be about edge-scenarios. Allowing someone to configure parameters that were never spec'ed to be configured is feature-creep (gold plating, extra coding, call it what you will), and I agree should be avoided and adds unnecessary (or not obviously necessary) "complexity".

    Handling an edge criteria that was implied but not explicit in a specification is what is typically meant of "corner case", and is not the same thing you described. Recognizing that the customer asked for something logically impossible (they want two data sets to reconcile, but they are at unexpectedly incompatible cardinalities), or something that, upon investigation while building an app, wasn't precise enough (they asked for this to be their standard green, but their standard list only includes red and blue).

    It's nearly impossible to specify all of those prior to coding, which is why the typical "waterfall" development techniques have fallen out of vogue. You're always going to learn things while coding, and this is one of the main contributors towards apparently unnecessary complexity. If I design version 1 of a program perfectly, and customers have new requirements for version 2, it's unlikely that the "simplest" implementation of version 1 will be the one that is most conducive to an upgrade. You end up with a choice between refactoring completely or sacrificing some efficiency and simplicity to graft the new features onto an otherwise good version 1.

    I think Dr. Dobbs is nitpicking, though. There are definitely many ways to address, measure, or understand simplicity, and I agree that it should not be THE goal in and of itself. But the idea of making code easy to read, easy to understand both in the micro and macro sense, and just generally "simpler", has many merits.

  • by plover ( 150551 ) on Thursday June 27, 2013 @03:54PM (#44125547) Homepage Journal

    The efficiency of a system can not simply be measured by CPU cycles. It all depends on where your costs are. Efficiency has to be measured by money.

    If your highest costs are in runtime efficiency, then yes, you need efficient code. But if your highest costs are in end-user time spent entering data, usability beats efficiency. If your highest costs are driven by software engineering practices, such as testability, reliability, supportability, frequent deployments, etc., then readability becomes far more important than efficiency.

    The usability argument works like this: if I have to pay a barrista $10 an hour to touch 20 buttons just to place an order for coffee, and the user time per button press is 3 seconds while the system time per button is 8 milliseconds or less, the efficiency of the code is almost irrelevant. My development investment is best spent in reducing the number of button presses. If a fancy GUI and a magical "do what I want" button reduces the 20 button touches to 10, I can save 30 seconds of labor per cup of coffee. If adding that fancy GUI increases the system time from 8 milliseconds to 30 milliseconds per button press, I haven't actually incurred any additional labor costs because the system is still faster than an average human's response time (maybe not in a highly caffeinated coffee shop, but it's still far less important than saving even a single button press.)

    I've found that in most business applications user time is the largest expense, by a very wide margin.

    If libraries of tested proven code are cheaper than hand written assembler, I don't want to pay a developer to replicate that work, even if it would be theoretically more efficient - unless the program that they're working on has efficiency as the most important goal. If I was developing an algorithm for slinging polygons at a graphics card, you better believe I'd squeeze every cycle out of the GPU. But if I'm figuring tax on a cup of coffee, or the total of a chart on a web site, efficiency isn't nearly as important as provable correctness.

    Lest you think I'm trying to defend the stupid walled gardens of iOS and their ilk's practices of constraining UIs and simpleton features, I'm not. I do think that there needs to be a mix, however. To use your iPhone rant, first remember that the iPhone is sold to completely average people, therefore, a simple UI is the primary requirement. (In other words the "dumbwagon" must be the default.) Furthermore, it should be restricted so that Joe Average can't accidentally screw it up to the point where it's impossible for him to recover to the dumbwagon state. Beyond that, however, everything else should be possible - there should be advanced configurations, user scripting, compilers, all that stuff that makes a computer do what I want. (And that's why I hate Apple.)

After an instrument has been assembled, extra components will be found on the bench.

Working...