DISQUS

Virtuous Code: Simplicity is Complicated

  • thesaj · 1 month ago
    I often feel people confuse "simplicity" with "efficiency".
  • avdi · 1 month ago
    Ironically, I've seen some of the most overcomplicated systems justified in terms of efficiency.
  • thesaj · 1 month ago
    I'd postulate that most of the overcomplicated systems are justified in the name of efficiency.
  • Joe Van Dyk · 1 month ago
    I would use #sum instead.

    Granted, that's defined in ActiveSupport, but it's probably something that's used common enough.

    times.sum { |t| t.to_time }
  • avdi · 1 month ago
    Thanks for the note. The original challenge those examples come from was a pure-Ruby challenge, so the entrants would not have had ActiveSupport available to them.

    A question for you: what does your choice to use ActiveSupport say about where you prefer the complexity to be?
  • chii · 1 month ago
    what you missed is the concept of essential complexity and accidental complexity. If a problem has essential complexity, no amount of simplification will make the complexity go away. e.g., designing complex concurrent systems that must be on all the time, is like that.

    accidental complexity is introduced when the programmer made a design error, or implemented, or decided to use the wrong framework to solve the problem at hand. square peg in a round hole so to speak.
  • avdi · 1 month ago
    This is a legitimate point, and you're right that I didn't address it. I've also seen the words "complexity" and "complication" used to differentiate: complexity is an inherent property, whereas complication is something that people add. In this article I'm talking more about the language people use when they have stripped a problem down to it's core complexity and are deciding how to distribute that complexity.

    Thanks for the comment!
  • paul · 1 month ago
    D'oh! I just noticed that chii already made this point, but I see a useful distinction between essential and accidental complexity. Essential complexity is the "air pocket trapped under plastic" kind. Whereas, accidental complexity is introduced by the way that you solve the problem, and could be eliminated by using a different solution. Accidental complexity should definitely be eliminated.

    Second, I see the issue more as one of readability, and simplicity is part of this, because human beings can only hold so many things in their mind at once. Your first example may be easy for a Java programmer to grasp, but may actually be harder for a Ruby programmer to grasp, and vice versa for the second example. This is because each language has its own idioms, and moving outside of those idioms (while not to be totally avoided) should be done with caution.

    I have a problem with people writing "Java code" with Ruby, and writing "Ruby code" with Java. That is what creates readability problems, and perhaps complicates someone's attempt to understand the code.

    More here:
    http://paul.stadig.name/2009/10/simplicity-and-...
  • avdi · 1 month ago
    Paul, as I replied to chii, this article is definitely about how talk about essential/inherent complexity and doesn't really deal with the accidental kind.

    I have pretty strong opinions about the the virtues of different styles of coding - I tend to agree with you, for instance, about staying within the idioms of the language. I tried to keep my opinions out of this article, however. The intent was to provoke reflection on what our definition of simplicity is says about our preferences regarding where the complexity belongs.

    I'll definitely check out your article!
  • jgoslow · 1 month ago
    I think simplicity should describe how you organize that pocket of complexity, perhaps by subdividing it into smaller pockets, which are simply organized... and second to the accidental and essential complexity. I think getting down to what is essential.
  • Tim Ottinger · 1 month ago
    I think you confuse "simple" and "clear" here. I think they're not the same.

    You can get a handle on "complex" by counting the number of moving parts: variables, operators (including "."), etc. You can have very simple code that is cryptic or simple code that is clear.

    Clarity is about communicative power, and that depends on shared experience with the target audience. This is a tough goal, but you can find some further commentary here: http://agileotter.blogspot.com/2009/03/simple-a...

    Another problem with "clear" is that it depends on how much the context can be taken for granted. If the complexity is hidden away, but you must interact with it "just so" then you have smaller code (simple=less complex) but it has a great "implicity" (having prerequisites to understanding). There are a great many ways to be unclear. I think that is a separate concern from "simple".

    The other thing about "simple" is that others confuse it with "easy to write". As you mention, sometimes the easiest change to write is not simple at all, but introduces complexity in moving parts and unclarity by having more modes of failure and modes of misunderstanding.

    Here is a conversation from a while back:
    http://blog.objectmentor.com/articles/2007/06/1...

    I think that we need simple (fewest moving parts) and clarity (fewest modes of misinterpretation) but I don't have a good way to measure the latter.
  • avdi · 1 month ago
    Great insights, Tim. I'd think a lot of programmers confuse simplicity with clarity, which is a delineation I failed to clearly (heh) draw out in this article.

    I love the word "implicity", I'm going to use that in future.

    Thanks for the links, I'll check them out!
  • eyston · 1 month ago
    "As an exercise, try to rephrase it in terms of where you are pushing the complexity"

    I love this line.

    One of my previous employers was distrustful of 'programmers' due to previous experience. When we would be defining a program and its scope 'simple' is the term that would be used frequently in keeping the scope of the custom software limited. This seems perfectly reasonable until you realize that by keeping the program simple we were shifting complexity to the user.

    Instead of a task based UI that was cognizant of the business rules, we would have a data based system were those business rules must be known by all users (and consequently fixed by the Help Desk when they made a mistake). But the software *was* simple.

    My personal goal was to build software that was easy to use even if it was complex.

    It is like the Zen of Python:

    Simple is better than Complex.
    Complex is better than Complicated.
  • avdi · 1 month ago
    Your example reminds me a little bit of a pet peeve I have about certain ticketing systems (Lighthouse being one example): a drop-down selector for ticket status. This is workflow, I don't want to pick a status from a list. I want to see a button that lets me advance the ticket to the next state, and a button to back it up to the previous state in the workflow.

    A pick-list of states is certainly "simpler" from the programming side but it imposes an additional cognitive burden of complexity on the user side.
  • Rob · 1 month ago
    In terms of logic, both examples are the same. They both perform the same action, and outcome.

    Whether the 2nd example is more readable is subjective. I definitely agree with the comments about having fewer moving parts, and few points of misinterpretation.

    If you're doing proper TDD/BDD you should only have the minimum amount of code required to pass each test anyway. Coding standards are a great way of getting your team on an even grounding. Using .Net we can enforce it with StyleCop and have intellisense suggestions in Visual Studio as you type. Pairing is another good way of making sure you and others will understand the code.
  • avdi · 1 month ago
    As regular readers know, I'm a huge proponent of both BDD and pair programming. I find that, if anything, frequent pair programming has opened my eyes to the diversity of opinion between different programmers regarding what is "simple" and what is complicated.
  • jvoorhis · 1 month ago
    There's also that other kind of complexity. The first example runs in O(N) while the second requires O(2N). It likely wouldn't have made much difference in this context, but sometimes code complexity does matter, and you have to write your code less "simply". You don't need to fall back to writing loops, but you won't get much use out of those pretty Symbol#to_procs.
  • Channing Walton · 1 month ago
    Last year I would have found your first example simpler. But after working with scala, I parsed the second version almost instantly and I don't know ruby. The first example now takes me significantly longer to grok.

    When there are fundamental principles being used to express something concisely then things are simple. Having to learn about those principles is necessary though, but many confuse having to learn those concepts with complexity in the solution that uses them.
  • avdi · 1 month ago
    And yet the complexity is still there, you've just internalised it. This is an example of what I'm starting to think of as the accessibility/expressiveness continuum: do we push the complexity out in the open to be more accessible to the lowest common denominator, or do we count on certain principles being pre-loaded in the readers' brains and realise the benefits of greater expressiveness?

    Thanks for the comment!
  • Channing Walton · 1 month ago
    Last year I would have found your first example simpler. But after working with scala, I parsed the second version almost instantly and I don't know ruby. The first example now takes me significantly longer to grok.

    When there are fundamental principles being used to express something concisely then things are simple. Having to learn about those principles is necessary though, but many confuse having to learn those concepts with complexity in the solution that uses them.
  • peterwilliams97 · 1 month ago
    As you say, simplicity is a difficult concept to pin down. However people have been making software for a while and it possible to look back and see which types of simplicity have worked best in practice. For the type of work I do (servers, embedded systems and shrink wrap software) the types of simplicity outlined in http://en.wikipedia.org/wiki/Unix_philosophy have won hands down over and over again.
  • avdi · 1 month ago
    Indeed. When choosing a "default" philosophy of design, I think Unix philosophy of small, sharp, composable tools is one of the safer bets.
  • reboltutorial · 1 month ago
    As a scientist, I would say refering to the concept of entropy:

    Make things Complicated is Simplistic, make things Simple is Complex ;)

    Complex = Reduce to the most simple things as possible but not less (paraphrasing $Einstein: make things simple but not simpler).
    Complicated = SmokeScreen which hides the Simplicity.
  • OldGuy · 1 month ago
    I learned many years ago to avoid using the word "simple" or "easy" in any discussions with either other programmers or especially customers/clients.

    While these words express only relative concepts (something cannot be simple or easy on its own, but in comparison to something else), most people hear them as absolute and interpret them to mean that the work will be done quickly or cheaply.

    Words like "straight-forward" more accurately express the intent almost every time.

    Making your code straight-forward is a matter of making it understandable and malleable by the expected audience. You have to expect the others to have a certain skill level and write to that level, even if it is "simpler" than your own. That's how teams work.
  • James Smith · 1 month ago
    This is neat. But i do not agree that simplicity is complicated. It only gets complicated when we try to make it simpler
  • carmenhilton · 2 weeks ago
    The titles says it all... Excellent post.
  • stevegoodman · 4 days ago
    Great post! I have nothing to add to all the insightful comments below, other than to say thank you for writing such a thoughtful piece.
  • avdi · 4 days ago
    Thanks for your kind words, glad you enjoyed it!