This article follows on from Inspired by HyperCard and User Programmable Apps.
Should software be editable by users? In User Programmable Apps I argued that it should. In this article I want to lay out two areas of software architecture required to allow user editing of software: component-oriented architecture, and event-based scripting.
But first an example…
Linn’s Kinsky App
Linn could almost be described as the Apple of audio. They have a high regard for the purity of the audio signal. The company started in 1973 with the Sondek LP12 turntable, turning the audio world on its head, which previously believed that all turntables were largely the same. They then made their own speakers, then amplifiers, before controlling the entire audio chain. Not content with the quality of audio recordings, they started their own record label. Now Linn controlled everything from the time the original sound waves were captured until they were reproduced in your living room.
As an interesting aside Linn once developed their own object-oriented CPU called Rekursiv.
In 2007 Linn made a pioneering leap into streaming audio with the Linn DS network music player. In 2010 they made a surprising announcement that they were no longer going to be manufacturing CD players.
I provide this background to indicate how innovative and forward thinking Linn are as a company.
Enter their app for controlling the DS, Kinsky:
It’s worth noting at this point that Linn write all of their software in house (including their website, etc). Also worth noting is that Linn have open sourced most of their software: http://oss.linn.co.uk/trac. And for the technically-inclined Linn are using predominantly C# to support cross platform desktop and mobile apps.
Okay, to get to the meat and bones, the Kinsky app has one major problem: there is no way to play a song and then have the following song automatically play. That is, if you select to play a song, all you will hear is that song, none of the following songs. You can queue up additional songs using the ‘Play Next’ and ‘Play Later’ options, but you will need to do this manually for all of the following songs. In fairness the desktop app allows you to select multiple tracks to play next, but who wants to do that (plus there is no equivalent on the mobile apps)? What you can do however is play an entire folder (album) at once.
It seems to be a major omission on their part. To make matters worse the Kinsky app has been replaced recently with a new Kazoo app, which has a major UI redesign but still doesn’t support the standard expected feature of a music app which is to play a song and all following songs. It’s such an omission that it must be intentional. Reviewers point it out, forum posts point it out. It is likely that Linn have an opinion about how music should be played, possibly harking back to record players, where the entire album is played, not just a single track.
But… what if you want to start at track 5?
You could use another app, except that Linn uses proprietary protocols and no other network music player apps can control Linn DS products. Linn’s software is open source, you could download the source code and make the edits yourself. But then you would need to learn C# and their entire software architecture, and then build and release an entirely new product.
This is a perfect example of the need for user-editable software architecture. The user should be able to add a new button or menu item (or gesture), and then some high level code to play the current song and all following songs in the folder.
Note that the software is currently open source, so theoretically someone could make the changes, so what is the difference between open source and user-editable?
Open Source vs User Editable
Before we focus on what an end user may not be able to do, let’s focus on what they may be able to do. An end user may be:
- Intelligent
- Logical
- Passionate about the software they are using and making it better
- A domain expert in the area of the software
- Willing to commit time to making the software better
- Able to contribute other skills beyond software development
Now lets look at what an end user may not have:
- Any programming experience at all
- An understanding of how computer systems work
- An understanding of development environments such as IDEs, version control, etc.
The question is whether end-users can make valuable changes to software given the skills they don’t have and the skills they do have? I argue that users can make valuable changes to software with the skills they have and the main two areas that will enable this are components and scripting.
Components
What are components? This deserves an article to itself, but in essence, a component is a completely self-contained software module which may, and usually will, have a UI. An example could be a button. A button has a look, feel, and behaviour. Conventionally a button is part of the UI framework and often shares code with other parts of the UI framework. Conventional buttons however aren’t true components in that it isn’t possible to move the entire software representing the button to another project. But a button could be implemented as a component. A 3rd party developer could build their own button and distribute it in a library for other developers to use.
A component has the following characteristics:
- Self-contained (although can have dependencies on other frameworks)
- Distributable individually
- Contains the code and resources for the ‘look’ of the UI (if it includes a UI)
- Contains the code for the behaviour of the component
- Ultimately it should also contain documentation for how to use the component
Component architectures have been around for decades. Component architecture doesn’t necessarily mean user editable, in fact it rarely is. However, I believe it is necessary to have a component architecture for software to be user editable.
What user-editable functionality should a component architecture afford?
As mentioned, a component architecture isn’t necessarily user-editable. What would it mean for components to be user-editable?
Firstly users should be able to modify the existing components on a screen. This would mean allowing users to reposition components and change attributes such as colour, font, and size. This is something most users would be familiar with working with applications like Word and PowerPoint (or Pages and Keynote).
Secondly users should be able to add new components. These components may come from a built-in palette or they may be sourced externally.
Setting the boundaries
Note that in the Kinsky example the software was already fully open-sourced. The key isn’t to allow the user to edit everything. Only things that a) would be easy for the user to edit, b) the user would want to edit, and c) you want to allow the user to edit. It is quite reasonable that some aspects of the software wouldn’t be user-editable.
It’s the boundary between user-editability and developer-editability that causes the headline of this article to have the words “Software Architecture”. You are no longer architecting the software just for developers to be able to edit, you are now including users into some levels of the software architecture. This new software architecture isn’t to make software easier for you to develop and maintain, it is to incorporate users into the process. It could potentially make some development easier, however, it most likely will be more work to consider the user-editing interface in addition to the conventional user interface. However, I believe this will become a major expectation of users in the future and as important as what we now call user interaction.
Other Component Architectures
As I mentioned in the last section, components deserves an article to itself. However, I want to mention one component architecture which certainly serves as inspiration for these ideas: OpenDoc.
Apple developed OpenDoc in the early 1990s as a document-centric component architecture. Before going any further I would argue one of OpenDoc’s flaws was that it was document-centric rather than app-centric (the plethora of mobile phone apps demonstrates this point).
OpenDoc was implemented in C++ and was quite unique at the time in that it was open sourced to developers. OpenDoc was an immense implementation and one thing holding it back was memory usage. The typical Mac at the time had between 2MB and 4MB of RAM, OpenDoc would easily consume 2MB of RAM (obviously not an issue today). OpenDoc was based on IBM’s SOM (System Object Model) and CORBA (Common Object Request Broker Architecture). OpenDoc supported user scripting through AppleScript.
OpenDoc got the knife when Steve Jobs returned to Apple. Interestingly the reasons given for cutting OpenDoc don’t make a lot of sense. When questioned at the WWDC 97 Steve Jobs explained that Java would replace OpenDoc. This is strange for two reasons, 1) Java is a language, and perhaps a library, but not a component architecture, and nothing like OpenDoc (and OpenDoc wasn’t a language), 2) Apple ended up not supporting Java to the extent of not including Java at all on its modern systems.
I believe the main reason Jobs cut OpenDoc was because it was an immense piece of software, consuming considerable resources, with no clearly defined vision. I also think it is possible Jobs didn’t appreciate its document-centric approach given his preference for consumer-style apps.
There are other component architectures but I will leave those until another article.
User Scripting
Do we want users to code? Yes and no. Keep in mind that if we are not using the word ‘developer’ then we aren’t expecting users to be able to do what a developer can do, such as manipulating pointers, understanding complex abstractions, functional programming, etc. But that doesn’t mean that users aren’t willing to instruct computers to perform a series of actions in response to an event.
There are a couple of questions:
- What is the boundary between developer-editable code and user-editable code?
- What features in a programming/scripting language would a user require?
I will tackle the second question first. The main aspect of the scripting language isn’t about how powerful it is, but how intimidating it is for the user. Most people struggle with programming not because it is difficult or they don’t like it, but because there are a series of brickwalls that are encountered when learning to program. The ‘true’ programmers push through these brickwalls and become expert programmers. Non-programmers stop at the brickwall and don’t progress any further.
One example would be a non-programmer viewing the source of a webpage. For most people there would be zero motivation to understand what it does, it’s completely non-sensical. And if they did feel inspired to understand more after a day of learning they still probably wouldn’t feel much more confident in editing the source of an existing webpage.
I believe the most important aspect of a user-oriented programming language is not how powerful it is, but how it psychologically encourages a user with little programming experience to want to understand what the code is doing and feel drawn to change it. This is similar to a good UI. Present a user with a command prompt and user manual and most users will run a mile, but present them with a user interface that is concrete, familiar, visual, tactile, tangible, and they will happily interact and explore it. User programming languages should be the same.
The specifics of the programming language will be left for another article. What I’m interested in exploring in this article is the boundary between what should be exposed the user and what is only seen by the developer.
The User Scripting Boundary
Developers will need to recognise that there is a user scripting boundary. This means that parts of the software needs to be accessible by potentially a completely different language in a completely different way, potentially with different data types and calling mechanisms.
The boundary can be approached in a similar way to a library. Even though the software may never be distributed as a library as such, users will interact with it as if it is. But unlike typical developer-oriented libraries, the interface will need to be simpler for users. So for example, there won’t be 10 functions which are required to setup and initialise a 3D view passing back and forth pointers, instead there may be just be one function(or ideally none if it can be done visually).
Developers will have to think about a user-code boundary. What will user-coders want to do with the software? What level of detail will they need? How simple should it be? What documentation is required?
It would be great if software components were self-documenting. Apple’s AppleScript architecture was self-documenting. Applications that supported AppleScript would include documentation for each Apple event in what was called a ‘dictionary’. Using Apple’s AppleScript Editor users could open application dictionaries and read the documentation. Components should include their own documentation embedded in the component itself. Users should have easy access to it in the script editor.
Conclusion
I’ve tried to provide an indication of the two aspects that a user should be able to edit in an application: components and scripts, as well as an indication of the boundaries between these two and the impact that would have on the software architecture of the remaining app.
There’s a lot more that can be said about the component architecture and scripting language, which will need to wait until future posts.