Engineer Thinking

I made a remark on Twitter the other day that gave rise to a discussion, and a few of the comments exemplified something I want to briefly talk about.

The actual topic of discussion isn’t particularly germane to my point, but suffice to say that it concerned a situation where Xcode (the development environment for Mac and iPhone/iPad programming) wasn’t doing anything to assist in a very common situation where you’d want to choose one of two possible courses of action, due to an underlying feature of the programming language used.

In probably more than 80% of cases, one particular choice would be made. My point, of course, is that Xcode ought to default to the most common choice, but transparently allow overriding that choice if the other option was needed.

Many people readily agreed, but there were two other types of response which stood out. They were:

  • Xcode can’t know for certain which choice you want.
  • It’s not Xcode’s fault anyway, because it’s due to an underlying feature of the programming language.

Both these responses illustrate what I call engineer thinking, and it’s something that’s both understandable but also incredibly damaging to the user experience of software. (A brief note is appropriate here to say that I’m a software engineer myself; I’m not just pointing fingers.)

Engineering in the real world has taught us (usually the hard way) about tolerances and precision. The axle must be of uniform strength, the furnace must run at a controlled temperature, the structural properties of supporting columns must be carefully designed. Reality tells us that being exacting, and producing the same outcome each time, is the key to not only reliability but even to feasibility itself. That’s all well and good, and has given us our civilisation.

But a problem arises when you allow precision-based design principles to hinder user experience. All too often, when faced with a decision about how to implement certain functionality, engineers take the extreme position that:

  1. A feature must be exactly what 100% of users want.
  2. If the above isn’t true (and it almost never is), the feature must be configurable.

This binary approach is gravely wrong, and unjustly offloads decision-making onto the user of the software. We’ve all seen where this approach ends up: multi-row sets of tabs, scrolling panes of checkboxes, nested radio-buttons and a general overload of configuration.

It has become increasingly difficult to avoid choices in our daily lives, to an extent which many of us find intrusive and counterproductive. Buying coffee in a shop you’re not familiar with leads to momentary paralysis as you work out how to convey the fact that you just want a regular, black filter coffee. This isn’t the way forward.

From the user’s perspective, there is always a default. The engineer will then argue, correctly, that different users will have different opinions as to what that default should be, but here the Universe steps in and reminds us that there’s always a “usual way”. There is always one particular behaviour or configuration or setup which suits more people than any of the others (surprisingly often, there’s one which suits more people than all the rest put together). That is your default behaviour.

The existence of uncertainty is not an excuse for exposing it to the user.

It is software’s responsibility to mask uncertainty and to make the effort to provide a sensible default behaviour. Many users will care more about the fact that there is a default than what the default is. Choice means decisions, and decisions mean effort and second-guessing, and loss of focus and time. The best choice in software is a choice which has already been made for you, invisibly.

There are of course situations where choice is needed, as indeed in the case which spawned this discussion. The key realisation is that there are different ways to present choice. Too often, we’re given choice as a first resort; instead, present choice as a last resort. If the user must be able to choose, then let them do so by overriding a sensibly-chosen default behaviour – and ensure that such situations are as rare as you can make them.

Software cannot just wash its hands of issues of technical complexity or uncertainty; it’s not remotely OK to simply offload that work to the user. Software intended to help with a given task has an implicit expertise; we assume that our photo-editing software knows more about photo-editing than we do. Expertise carries a duty of care whereby the expert is expected to provide the benefits of expertise without the full cost of knowledge. That’s why experts are useful! The same holds for software.

The primary expression of expertise is in knowing effortlessly what the right course of action is in a given situation, and carrying it out without micro-management or endless justification. Make your software such an expert, and a guide and assistant to the user. Don’t force the user to make your software’s decisions for it, or to repeatedly bow down before its keen grasp of the vagaries of choice and uncertainty.

It all comes down to a question of art. Our art (that of software engineering) is not in making it work. If you see it as a significant success that you managed to name some methods, or write code that compiles and runs (or implemented a heap sort, or found the bounding box for a set of points, or parsed some XML), then your career goals are low indeed. Anyone in this industry can do that stuff, including any reasonably proficient final-year undergraduate in Computing Science. That’s core-skillset, vocational learning. You’re not aiming high enough.

Our art is in making the abilities of our software accessible to those who do not know how it works.

Your chance to demonstrate skill and professionalism and genius is by effectively hiding all the circuitry and wiring and batteries and screws behind one big shiny “Get the Job Done” button, whose apparent function is almost magical.

If you’ve exposed underling complexity or unnecessary choice in your software because you see those things as inevitable, it’s because your job isn’t finished. If you’re going to write GUI software for other people to use, do it properly, and treat those people like human beings instead of software engineers. If you want to expose complexity to the user and wash your hands of it, write command-line tools – or utilities that are used exclusively by other machine processes.

You can’t have it both ways. Writing GUI software is for people who strive for excellence not only in the “software” part but in the “GUI” part too.

If you enjoyed this article, you might be interested in following me on Twitter, enquiring about my iPad (and iPhone and Mac) development services, or listening to my thoughts on software design on The MDN Show podcast. I’ll also quite shamelessly link you to my Amazon wishlist.

23 comments

  1. Hey Matt,

    Great article, thanks for putting words on this feeling I have.

    Thomas.

  2. I think you hit it on the head, as always. Software has to be designed for humans not engineers since in the end they eventually become advocates for the software’s success.

  3. Very nice piece! I’ve been privately using the exact same term for a long time do describe these problems (often my own). It’s good to see I’m not alone with it! “Engineer Thinking” is a very bad thing, especially when it’s trying to mask “Engineer Laziness/Insensitivity”. On the other hand, I might add, that the two required disciplines engineering and UX are in many ways polar opposites and it’s very hard to combine them in one person or even one company. But we will have to learn it, no doubt.

  4. Well, said Matt. You make a lot of very good points that every software engineer should be thinking about when designing and developing any piece of software that has any degree of user interaction regardless of the platform.

  5. Sebastian Koch

    “There are of course situations where choice is needed, as indeed in the case which spawned this discussion. The key realisation is that there are different ways to present choice. Too often, we’re given choice as a first resort; instead, present choice as a last resort. If the user must be able to choose, then let them do so by overriding a sensibly-chosen default behaviour – and ensure that such situations are as rare as you can make them.”

    This paragraph needs more emphasis!
    It is crucial that the software makes important choices transparent. In the code editor context the developer needs to be able to see that a choice has just been made for him. Otherwise this could lead to a long bug-searching session and a lot of anger at the end once you find out that your editor made the wrong choice.

  6. This “Software as the expert” concept is great! I’m definitely taking that to heart.

  7. Hey Matt, great article, but in your second paragraph you might have thought to put “you’d” into context so as not to lose the attention span of your audience as they stop for a moment to figure out who you are referring to.

    Xcode…wasn’t doing anything to assist in a very common situation where the user of an application would want to choose one of two possible courses of action…

    Nevertheless, it’s a good piece and totally agree with your point of view.

  8. [...] “Engineer Thinking” by Matt Legend Gemmell: If you’ve exposed underling complexity or unnecessary choice in your [...]

  9. [...] Matt Gemmell brings up an interesting point in a recent blog post regarding user choice and defaults in software design. [...]

  10. [...] The Single Page Interface Manifesto Dynamic Charts with HTML5, Canvas, and Flotr for Prototype Engineer Thinking @font-face [...]

  11. This is what I tell my managers constantly. The user’s need to look at software and understand it. Why go completely custom and define a new paradigm they users can’t look at at and say aha..

    This is a great article!! Every engineer and designer should read this article and chant “Our art is in making the abilities of our software accessible to those who do not know how it works.”

  12. [...] I’d start todays post with a quote that Kirill proviously linked to. The quote is from “Engineer Thinking” by Matt Legend Gemmell: If you’ve exposed underling complexity or unnecessary choice in your [...]

  13. While I do agree wholeheartedly with the sentiment expressed, I wonder why you assume that it’s the /software engineer/ who couldn’t make up her/his mind?

    In my experience, more often than not, it seems that engineering has an opinion on which single option to implement but different customer-factions can’t decide on one way to go and compromise by asking for a configuration option.

    • In the context of pushy client or a poor project manager, I agree with you. In a broader context this may not be relevent though.

      My company is working with a vendor to design a large interactive website and they epitomize “engineer-thinking” every single step of the way, designing horrible user interfaces at every possible interchange. They all work, but only the designers can figure out how to use them and in what sequence to push what buttons. (I’ve been trying to convince management to fire them for months, but the price just speaks too loudly).

      The point really is that we could all be doing a much better job, even if there are some battles that can’t be won.

  14. This reminds me of the Perl philosophy: “easy things should be easy, and hard things should be possible.”

  15. [...] Engineer Thinking » Matt Legend Gemmell – Good article about how we should be striving to make GUI's (and I guess by extension software) easier to use. [...]

  16. No.

    Our art is one carried out deeply underground, buried beneath levels of abstraction and intricacy more numerous than in any other man-made field.

    Our art is like that of the clockmaker, creating gears and hammers to strike at the right time, every time.

    Our art is in taking the seed of an idea, and envisioning its germination, as well as the full-grown and complex plant at maturity, and building a trelliswork that allows it to grow and flourish.

    If your exposure to our art has been limited to ‘calculating bounding-boxes’ and ‘parsing XML’, then I’m sorry for you, but perhaps you should not go around lecturing people about ambition.

    What you describe is the art of human interface design. A field that relates to software engineering as architecture does to structural engineering, or as food photography to cooking.

    An important field, certainly. But a different field. And a different art.

  17. You’re preaching to the conoverted when addressing (experienced) engineers. Tell the marketeers and managers who inevitably know better and call the tune and make my life for one frustrating to say the least

  18. [...] just found an article called Engineer Thinking on Matt Gemmel’s blog. If you are at all involved in the development of GUI software, you [...]

  19. A very long time ago I came across a simple mantra which encapsulates the ideas here:

    Don’t ask the user questions they don’t understand

    If you apply this rubric to all the interfaces you design, you wont go far wrong.

  20. Christopher Lohman

    Well done…I have been preaching this to software engineers for years. When I was manager of customer support years ago for a software developer I developed a fondness towards software that is built as follows:
    1) Accept that you’re not designing the car, you’re simply building the engine. Build it so that you can run everything from the command line. You as the developer should be able to drive your product without a gui. This gives your product full flexibility without the hassle of building all of that flexibility in to a gui. Allow your endusers to drive the product without the gui. (Macro/Scripting language)
    2) Allow the ability to enable logging of everything possible, up to full run-time logging. This means that most of your code should have a corresponding debug echo that can be enabled/disabled with a switch. In an ideal world your application will have a “tail -f” type gui window that can be enabled in order to watch whats happening under the hood. Your users will use this data to figure out what commands run when they interact with the gui. They will in-turn use this knowledge to develop new UI’s. Click level logging is a minimum.
    3) Build a skinnable gui. Every gui element should be built out of png images or some other standard image format. Even if you can optimize and improve on that format, don’t. You want your superusers to skin for you. Make skinning very very easy for the community. Users should be able to skin your product until it looks absolutely nothing like the original gui. Avoid frameworks that they must fit within. Allow skins to be shared. Build a community for it. Hold contests. Encourage it. Nourish it. This will turn in to free product development for you. (these days you might as well just build a gui out of html5)
    4) Hire an architect to design your ui. Only give them vague instructions on how your product works and let them decide how a user will interface with your engine. Avoid bringing them in to the office. Try very hard to never show them a prototype or test harness or anything else. The less you “poison” them with company ideas and culture, the more likely it is that you will receive a design that is nothing like what you were thinking of, and is exactly what the users will love.

Leave a comment