High-level goals for interactive software
1. Typical usage should be easy and efficient.
2. All expected usage should work correctly.
3. Unexpected usage should result in safe behaviour.
Clearly it isn't just unexpected usage that should result in safe behaviour and we would certainly expect that typical usage should be correct as well. But that hierarchy makes it easy to see the cascading importance of software properties in relation to the degree to which user behaviour is expected to happen. If we plot expected human interaction on a distribution curve then we can overlay the probability axis with one that indicates what level of behaviour the software should respond with. That probably made sense to very few so here's a clearer explanation.
Under no circumstances should software ever do something unsafe. Losing data or allowing it to be accessed by unauthorized parties are typical examples of failure at this level. Although I posit this as a minimum requirement for software, in practise both of these things occasionally happen because it is generally intractable to enumerate all possible things a user might do for any piece of software sufficiently powerful to be worth discussing. But there are tools like fuzzers that can help automate the task of searching for such problems.
For every action that a user might reasonably be expected to perform, software should respond in a manner that the user could reasonably expect. Put like that, it seems only fair! That level of behaviour is usually verified by manual feature and regression testing based on feature specifications. Because this level of usage is not typical, it is important to provide contextual user-assistance for it. Of course, users tend to assume that performance will scale linearly with the amount of data they provide. It is therefore important to keep these expectations realistic by detecting input data beyond the range of typically expected workloads and warn the user that they will produce uncharacteristically low performance.
Typical usage is what software is designed for and therefore using it in these ways should be discoverable (so that documentation is unnecessary), simple (so frequent usage does not frustrate) and efficient (even at the cost of code complexity, so that users do not waste their time).
It is illuminating to think about software evolution in terms of these three levels. Initial releases of software tend to have tiny sets of behaviour considered typical and large set of behaviour considered unexpected but as software matures, more behaviour moves away from being considered unexpected and toward being considered typical. This tends to increase the complexity of code unless it is refactored to account for the changing levels of expectation assigned to different user behaviour.
Anybody care to disagree?

As a corollary, unwanted or complex behavior should be actively discouraged by being tucked away in a menu somewhere, or deep in an advanced preference page.
Instead of deciding how users *should* use software and then designing
the UI to shepherd users into this mode of interaction, it's more
effective to watch people trying to solve the target problems without
the software to figure out how they already think about the problem
and then design the interaction model around their mental model of the
problem space.
A designer knows better than a user how something should be interacted with. For example, a programming language is restricted in certain ways and build to be used in a specific pattern; this is a strength, not a weakness.
Apple products are designed this way, and they have the best interfaces because of it. Microsoft uses the method of letting their users design their interfaces through user studies, and they have the worst interfaces because of it.
designers to slap together a template UI and then run a usability
study but that's not what I suggested. What I think they should do is
to watch people trying to solve the target problems using whatever
means they have been traditionally employing so as to gain insights
into how they think about the problem space. Only after that should
there be an attempt to design an interaction model for the new
software. In your example of a programming language, it is important
to discover what problems you wish to solve with the new language and
then watch how a variety of users currently handle those problems in
the languages they are already using before you try to design how your
new language will solve these problems. All of this will happen long
before you run a study to find small usability impediments in your
interaction model.
one yet! And you aren't studying the software that isn't yet built;
you're studying how people currently think about the problem space
that you wish to tackle.
concerned the level of expectation for software responses to user
behaviour.
Leave a comment...