Monday, November 14, 2011

The Principle of Least Surprise as a survival trait

It has been a while my last post.

I have been on a bit of a roller coaster at my workplace and home dealing with the fact that my productivity has been insufficient for all the things that I have taking on.

Thank the Gods for tools.

I will be writing about a number of new tools I've discovered and some tools that I have retired in the past few months but specifically wanted to talk about something very interesting I discovered in the last month that reinforces some old-fashioned developer wisdom.

One of my favorite principles that you will hear bandied about is the principle of least surprise (POLS). You can go to Wikipedia for the definition if you want (POLS) but I will summarize a key portion of it here:

"..when two elements of an interface conflict, or are ambiguous, the behaviour should be that which will least surprise the user; in particular a programmer should try to think of the behavior that will least surprise someone who uses the program, rather than that behavior that is natural from knowing the inner workings of the program..."

A week and a half ago I was involved in a training course that dealt with the latest findings of neuroscience/cognitive science with regards to the impact it has on people learning new things and shifting their behavior in organizations. It was actually much broader than that, but that was my focus when I went there. The course itself was very focused and pragmatic, rather than theoretical.

The fields of neurophysiology and cognitive science have had a lot of significant shifts in their accepted worldviews. A lot of what's happening in these fields is the natural result of our being able to directly monitor brain/nerve activity in ways we couldn't 10 years ago. It is probably
inevitable that as we started to be able to directly measure things there would be some surprises.

One set of typical discussions are to be found in "Cognitive Science". This volume contains a fascinating back-and-forth on the fundamentals of perception and cognition located in two different articles: "Situated action: a Neurophysiological response to Vera and Simon." By WJ Clancey. That's in Cognitive Science volume 17 pages 87 to 116, which is immediately followed by "Situated Action: A reply to William Clancey" by Vera and Simon. You typically won't be able to find something like this except in your nearest technical library (That's where I had to go). The set of articles highlight the difficulty involved in analyzing cognition when the only tool you have for direct observation is the process you are studying, itself. The attempt to tease out reality from observation is fascinating in of its own right. Not to mention the fact that in the articles both parties successfully avoided all of the usual subtle and vicious underhanded usage of verbal stilettos that so characterizes many scholarly exchanges. But I expect only a few Neuro/Bio geeks will be willing to make the effort to read them. Nor should you have to.

Rather than spending a lot of time giving you all the results of all of the research in a semi-scholarly manner I will instead give you a summary of the key point and direct you to some more popular presentations of the material.

One of the key points that has pushed to the fore (while confounding many cognitive scientists along the way) is that the brain for the most part is not processing in sequence. Our mental model for the most part has been: We perceive something and then either consciously or unconsciously choose an action. You will see terms in the literature like "reaction/action cycle" or "perception action cascade". The measured reality is counter to this. The brain for the most part appears to act as a high-speed parallel pattern matching computer constantly working to predict in the now what's going to happen next. Its operation is such that by the time you have received the perception (i.e. the perception has fully bloomed in your consciousness), you are already in motion. In effect action and perception arise concurrently with perception lagging behind action. You are already in action by the time you consciously perceive.

At one level it's very logical. In terms of survival humans are not very fast, not very strong, nor very aware. Predicting the future is a great tool for staying alive in those circumstances. Thus comes the old saw "We only learn from our mistakes." Learning from mistakes in a way that has you be in action to avoid them without being slowed down by conscious thought is clearly the way to go to avoid predators. It explains how boxers can block punches at a speed faster than they can consciously perceive. Your brain is taking the middleman of conscious thought out of the equation.

At another level it feels very illogical. Notice I say, "it feels". It really is an emotional reaction rather than a logical analysis of data. It especially appears counter to our own experience of our own experience. One of the downsides of trying to use cognition to analyze cognition.

Leaving aside all of the implications this has for living life (Just thinking about what this means for romantic relationships could get you into trouble), the implications for user interfaces are, to me, significant.

The principle of least surprise appears to be much more critical than we expect because we are dealing with an agent (the brain of the users) that is designed to be in motion before it has seen our nice pretty screens. It certainly means that usability testing becomes even more important because it is our only real on the ground way to evaluate the "survivability" of our user interfaces.

I am sure that I don't have a solid beginning of an understanding of the implications of this new way of looking at things. I am pretty sure that if we stop relating to our user interfaces as a work of art and craft and start relating to it the way the human brain is relating to it: another thing to
survive, we will have some breakthroughs in the way we design and test user interfaces. Of course, it does give rise to some great possible names for testing measurements and regimens like "Survivable User Quotient" and "User Interface Survivability Evaluation". We should be able to get some really great innuendo somehow. Maybe even a reality TV show "I survived your UI". We can even have SDD aka Survivability Driven Development.

I will just leave you with an example of a situation I deal with every day that illustrates this. I work with a development and training organization that measures everything they can to track the effectiveness of the courses. Everything from the percentage of people that complete the course to homework completion and so on. We have a website that allows us to track many of the statistics and the website is specifically designed with the intention that you pay attention when you put the statistics in. What this means that the user interface level is that for each set of statistics there are save and cancel buttons next to each row. The cancel button does what you would expect, it cancels the changes that have been input and returns you back to the previous state. The save button acts the way a "commit" button would for a revision control system, it commits the changes for the row in such a way that they cannot be altered without explicitly sending an e-mail to the person who manages the statistics and having her change them at the database level.

Being a developer who has learned from over 20 years of mistakes I save everything as I'm editing them. That skill is critical to my survival as a developer and has saved me a great deal of embarrassment (which will do for motivation until a real predator comes along). As a result I have routinely had to deal with sending e-mails to correct the statistics that I had partially
entered and saved along the way. It is been that way for three years for me and it will probably continue to be that way simply because my day-to-day tasks as a developer constantly reinforces the "survival" value of saving my work. If this was a user interface that I had a choice in working with I would automatically avoid it simply because it's usage goes counter to one of my good "survival" practices.

The Principle of Least Surprise, it's not just a good idea, it's survival.

Thursday, July 22, 2010

Java now has Objects

As far as I'm concerned, Java has always been a "Nearly Object Oriented" language. When translating a model into real code you end up specifying the properties of the object and the methods with the business logic and translating that into fields, methods with the business logic, and methods to make it possible to relate fields like properties.

Eclipse makes much of this easier with various code generation plug-ins and features yet, despite that, I have wasted hours writing, correcting, and and maintaining infrastructure methods such as equals(), getters/setters, hashValue(), toString() .

All that has shifted with the addition of Lombok.

http://projectlombok.org/

Project Lombok uses Java 5 annotations in combination with byte code generation to allow compile time generation of all of the infrastructure methods to have fields become properties.

For example:

You can use the @Data annotation on a class to automatically generate the toString, hashCode, equals, and getters for all fields and setters for all nonfinal fields. It will also generate a free constructor to initialize your final fields.

Voila ! Instant domain object.

If you want you can break these things down in a more à la carte manner by using annotations such as:

@Getter / @Setter
@ToString
@EqualsAndHashCode

It also has some annotations I have not yet played with or evaluated:

@Cleanup - Automatic resource management: Call your close() methods safely with no hassle.
@Synchronized - synchronized done right: Don't expose your locks.
@SneakyThrows - To boldly throw checked exceptions where no one has thrown them before!


To use it on an Ant based compile you simply include it in your class path. To use an eclipse you need to run the installer and point it at the eclipse installation in question. It will modify the eclipse.ini file so that the runtime compile of Eclipse will automatically process the annotations.

To sum up:

PROS:

  • Radically simplifies my life when dealing with business domain objects
  • Byte code generation is nicely hidden and transparent.
  • Simple to use for command line builds.

CONS:

  • Eclipse install requires additional work and documentation if you are documenting your build environment for someone else.

UNKNOWNS:

  • How well it plays with tools like AspectJ.

Tuesday, March 9, 2010

Elliote Rusty Harold has a interesting (i.e. causes me to think) mention of other ways for the commit, build, and release cycle to go. He is suggesting that build, commit and release is an alternative. Take a look.

http://cafe.elharo.com/programming/sourceforge-for-the-21st-century/#more-551

Tuesday, February 23, 2010

PIM Manfesto

Personal Information Manager Manifesto

A manifesto is a declaration of principles. It may sound grandiose, but this declaration of principles is important to me because it is the distillation of at least 7 years of thinking about what the future I want to create really is.

Principal: The PIM is an expression of how people live their lives.

The things users talk about in real life correspond to the things they manipulate in their PIM. For example if a person thinks in terms of anniversaries, holidays, meetings than those are the things they schedule rather than something called an event.

The actions users talk about in real life correspond to the actions they take in their PIM. If they think in terms of making and keeping promises than the PIM makes it possible to make and keep promises.

Principle: The PIM has a very minimalist design.

It displays what the user needs when it is needed rather than overwhelming them with all the information they might need.

Principal: The PIM is designed to use and make available connections between the things the user deals with.

The PIM makes available the connections between the data when the user needs them. It is easy for the user to lay out the communities in their lives the way they think of them. Adding and subtracting people from a community should be easy.

Principal: The PIM allows users to recognize what is available from where they
are rather than remembering.

Having the user be able to get the information they need when they need it and recognize its availability rather than remember where it would be.

I will probably add to or simplify this over time but I wanted to get it down in writing and out there.

Saturday, February 13, 2010

Build Tools - An incomplete paradigm - part 2

I am in the midst of making my build system for the saltations project usable by everyday developers. i.e. I am working to make it a turnkey system and in the process came across this entry in Kent Spillner's blog and nearly split my side laughing.

I don't know is he meant it to be funny but it was an accurate summation of most of my complaints about Maven and I liked his expression of it:

http://kent.spillner.org/blog/work/2009/11/14/java-build-tools.html

Ah, well, back to work.

Tuesday, February 9, 2010

If a language contains a hole, programmers will fall into it. All languages contain holes.

The above title is a quote from an article on error rates in scientific software.

The article is a straightforward and easy read with fascinating results for error rates in both C and FORTRAN code. This study used both static analysis of the code as well as a runtime comparison of 2 implementations of the same algorithms acting on the same input data with the same parameters. It is arguable that the results may not be limited to those 2 languages.

The error rates were not a surprise, similar error rates have been demonstrated over and over again in typical software. The types of errors were interesting as well as the impact that the sum total of the errors can have. In effect
"...
these 2 experiments suggest that the results of scientific calculations involving significant amounts of software should be treated with the same measure of disbelief as an unconfirmed physical experiment"
.
That is not a cheap dilemma.

We start talking about independent verification of complex software calculations, the costing man-hours and money goes up drastically. Yet I think it is obvious that the results of this research points strongly to that being the case.

Another interesting result is that there appears to be a clear relationship between the complexity of the language specification and the number of holes for a programmer to fall into. Probably not a surprise, but clearly not something that many language developers pay much attention to. In general, most programming languages produced these days have a much larger number of language rules than preceding languages.

The author makes an argument that program standards adherence in scientific software is laughable. I leave to your imagination and judgment how applicable that conclusion is to your own workplace.

Here is a pointer to the PDF article: THE T-EXPERIMENTS: ERRORS IN SCIENTIFIC SOFTWARE. Enjoy !

Build Tools - An incomplete paradigm - part 1

Dependency Management, Provisioning, and Repositories

I love automated build systems. I like letting the computer do the same thing over and over so I don't have to. In some respects I think we have started to come out of the dark ages of programming in that more people think in terms of continuous builds and unit testing then don't.

I didn't say that everybody does it, but it is a vocabulary that everybody has and can speak, even if they choose not to use it. 5 to 7 years ago the average opinion was that automated builds were overkill that only the wealthiest companies could waste time on and unit testing, while laudable, was considered something that most people didn't have time for.

Nowadays, when I interview, it is rare for me to encounter company that does not have an automated build system and some flavor of testing the code.

And given the quality of open source tools available for most of these tasks is rare that an enterprise has to bother spending money on the tools.

In one of my previous posts Ivy vs Maven, I mentioned that I do most of my dependency management using Ivy. It allows me to simply specify a dependency such as version 7.12 of DB4O And it will retrieve all the other dependencies that DB4O needs. A few put pointers to Ivy related material are below:

Automation for the people: Manage dependencies with Ivy

http://ant.apache.org/ivy/

It also has an eclipse plug-in so that the dependencies that you specify in Ivy are used by Eclipse in your projects.

IvyDE plugin. http://ant.apache.org/ivy/ivyde/download.cgi

In my world the advantage that Ivy has over Maven is that it's not tied to Maven's project structure the way Maven's dependency manager is. I can use it with Ant easily and powerfully. Maven on the other hand has a number of built in design assumptions ( such as thou shalt only generate one artifact (jar, zip, etc...) per project. If you are able to design your project from scratch and have it fit into the Maven project structure and design assumptions AND you don't have any need to do any coding of extensions to Maven then I would recommend using Maven. If not, I would recommend Ivy and Ant together!

These are all things that myself and others have all said before.

There are two areas of automated build systems though that often get overlooked. One I consider a solved problem and the other I consider a a royal pain in the butt. Those two problems are Artifact/Metadata repositories and the build system provisioning.

Let's talk about the solved one. Artifact/Metadata repositories are the storage area that Maven and Ivy go to to get metadata on dependencies as well as actually retrieves the artifacts themselves. The Apache Ivy project does not maintain any repositories themselves but they are coming able to talk with the Maven repositories. The Apache Maven project (or some related group of people) do maintain a repository. Of course, like many volunteer manned projects, the coverage of metadata and artifacts can be spotty at times. Overall though, it is an incredible gift that these volunteers give us.

Now we get to the steamy underside: Many open source projects for one reason or another, are unable or unwilling their artifacts and metadata in the Maven repositories. For some, like Google, it appears that many of the projects are not published to the Maven repository simply because their build system doesn't mesh well with the Maven toolset so additional work would be required to post these artifacts and metadata during each release. For others, it is ideological. For those projects they are avoiding going to Maven for a build system and avoid doing anything to support the Maven "ecosystem".

So this means that many artifacts and metadata about those artifacts are not available out of the box when you are using the Maven or Ant+Ivy build system.

In addition , even if all the artifacts are in the Maven run repositories, there is no guarantee that they will be available. There are many times in a week where the Maven repositories may experience slowdowns.

So I started by describing this is a solved problem. This is why: there are a set of companies out there that have put together repository software such as Nexus and Artifactory that act as repositories as well as proxies for other repositories.

At home on my build server I am running a copy of Nexus. I use Nexus primarily because when I first tried out Maven repositories Nexus was much more mature than Artifactory, I haven't revisited them in a while simply because I haven't run into anything that Nexus can't handle well.

Installation and running of Nexus is straightforward (At least on my Ubuntu server). It is already pointed to the key Maven repositories in typical use. All that needs to be done otherwise is to point your Maven or Ivy installation at the Nexus repository rather than the individual Maven repositories.

Pointing your Ivy installation at Nexus is as simple as adding the following line to the ivy-settings.xml:


<ibiblio name="nexus" m2compatible="true" root="http://kukri:8081/nexus/content/groups/public">



Which tells Ivy to use the ibiblio resolver (Ibiblio was the website that provided the first maven repository) and to assume that the repository is Maven 2 compatible.

After the 1st time a build system is used, those artifacts are downloaded by Nexus to the local Nexus repository and are available from then on without regard to whether or not the original Maven repositories are available.

I think that it is obvious that if you are going to use dependency management as part of the build process in the enterprise, you need something like Nexus that you are not at the mercy of Internet connectivity and website availability for your builds.

Does it cure everything? No. It is still a minor annoyance to deal with those artifacts that are not managed as part of any Maven repository and have to be manually uploaded to Nexus. It is not the upload process that is annoying, Nexus makes that easy, the real headache is keeping track of those artifacts that you may need to do this with.

Of course, once you have an enterprise artifact repository like Nexus installed you can just back that up.

Overall, in the business/commercial enterprise world, this solution works well as is. In the next posting I will discuss where this set of solutions is inadequate for a real world open source problem.