In this post, I’ll try to define a real problem — in one specific area of user interaction development.
Let’s say you’re writing a web app, and this web app has a lot of different interactions with the user. Two of those many interactions is entering user’s email and users’ job. So I have corresponding forms for users to do that. Luckily, this information is often present on Facebook, and Facebook provides an API. Therefore I decide to simplify user’s life by allowing him to fill this information from his Facebook profile. As a nice side-effect, I can inform him on Facebook whenever something interesting happens in my web app.
Fine. So I design my user flow in this way: in the first screen, I perform Facebook authentication and request from the user permissions to access his information. In the second screen, I use the information about his job to give him some meaningful interaction related with the web app. In the third step, I direct the user to his page, where he can proceed using and enjoying my web app.
Now I develop this feature. In the base class for all screens of my web app, I define the property to hold the actual permission set needed for this specific screen to work properly. By default this set is “email, job”, and just for the first screen of my user flow (where we don’t have permissions yet) this set is empty. Then I write a generic handling of permission sets that is same for each screen: before rendering, the screen would detect the permission set actually given to us by the currently logged in user, compare it with the permission set defined for the corresponding screen, and redirect the user to the Facebook authentication dialog if something is missing. Simple, logical and generic. Now, even if the user would start his voyage on my web app in the middle of my user flow, his missing permissions will still be properly handled.
I release the app, and invite users to use it. To my horror, 90% of users would drop off on the first screen – they just don’t give me the permission to use their Facebook profile. Unfortunately I don’t have means to ask them why. My hypothesis is that they don’t trust me just yet – perhaps they didn’t see my web site before. If this hypothesis is correct, asking for facebook authentication so early in the user flow is premature.
So I go and design a new user flow. The facebook users would be invited to my standard homepage. When (or if!) they use the functionality related with jobs, I will ask them to fill their data, and provide an alternative way to do that using Facebook. When they click on the Facebook button, I would display the authentication dialog, get permissions and then use the facebook profile data for my interaction.
Now, I want to develop this small change, but have to admit that I need to throw away my generic facebook permissions handling code. What I actually need, is the ability to display the Facebook Authentication dialog in some more or less random screen of the web app, get the permissions and use the data. But this is so different from my first user flow implementation!
Why it has to be so different!? I mean, what we have here, is a very typical flow:
- Input first data item from user
- Input second data item from user
- Use first data item
- Use second data item
And what I need is just reshuffle this flow a little:
- Input first data item
- Use first data item
- Input second data item
- Use second data item
And suddenly, it means a huge change in my architecture and in my code!
Here is another example of the very same problem, just to demostrate that this problem is not some rare special case. When user creates one new directory in Windows Explorer, Finder or Nautilus, he has to enter two mandatory pieces of data: the parent of the future directory, and its name. This is not just a coincidence of bad user interaction design: for some unknown reason, all file system APIs in the world are designed in the way that both data items are required. You cannot create an unnamed directory. You cannot create named directory without a parent either.
Now that’s pity. Imagine how much better it would feel for users, if both interactions were possible? The possibility to create unnamed directories would eliminate directories named “1”, “tmp”, “asdf”, “New Folder (74)” and similar shit every computer in the world has on its harddrives. This shit happens when I have created some useful piece of data, and I have to close the editor quickly, so I need to save the file, and no I don’t want to save it to my common documents folder where it can be lost in hundreds of other files. If I could create a new unnamed directory and store this file there, I would be able to return to this directory later and give it a reasonable name.
Parentless directories also make sense. You download a zip archive from the internet with some source code. It contains a dozen of subdirectories. You want to unpack it somewhere, build the software, install the binaries on your system, and then leave this parentless “somewhere” place, allowing thereby the file system to reuse it for other data (think automatic garbage collection).
So, let’s say you’ve decided you want to change the way how it works right now. Will it be easy or complicated to do? Well, that’s not user configurable – this has to be developed. With Microsoft and Apple you’ll have no luck persuading them to implement this change. But even in the world of OSS, the first thing you’d need to do is to agree and issue a new version of POSIX, defining the mkdir function allowing to create unnamed directories. And even if you’ll succeed with that, your next step will be to patch all several hundreds of already implemented different file system drivers to support this new function. And only then you’ll be able to patch your Nautilus to enable new user interactions. To summarize: this problem is intractable.
Seriously? I mean, just reshuffling the usage order of two simple arguments in a single trivial function is an intractable problem?
Well, solve it, and you’ll create the new mainstream language of the new generation.