Category Archives: programming

Code Writing from a UX Perspective

We often talk and discuss coding style and guidelines. Some of these discussions grow to be (some would say useless) flame wars, while others invoke thoughts and sometimes even reach a consensus, e.g. “GOTO considered harmful” (PDF). These discussions tend to be motivated by good intentions – making software development better; delivering software faster, with better quality and precision.

One area that keeps coming up is the need to have code written clearly; to make code easily understandable and changeable. It is generally agreed that code readability is important. And yet, the discussions are sometimes endless. We don’t seem to be able to agree what constitutes code that is written well enough, one that is easily understood. Claims made are often seen as very subjective and “a matter of taste”, as readability and code quality deals with human interpretation and judgement of said code.

At the same time, another field that deals with human-computer interaction seems to achieve better success in establishing at least some level of standard or agreed understanding of quality – software user experience (UX). Naturally, taste also plays a role in this case, but practitioners seem to agree more on some underlying practical principles to follow; similar to how coders have established some common understanding of good code design.

Which then begs the question – what if we approach code writing as a user experience problem, where the users are coders (incl. the code writer)?

Designers of applications’ user experience often deal with how the application is to be used. Characterizing its users and their main use cases. The answers to most of these questions are already known to us in the case of coders – we are the users. We write code, read it, test it, debug it. We know how we navigate code, skim through it, or how we approach refactorings.

Given that profiling the users is mostly out of the way, can we use this knowledge by taking a page from the UX designers’ playbook and applying it to code writing?
Can we design the code itself in such a way that will make our experience with it more productive and enjoyable, or dare I say delightful?

A naive approach would be to look at UI patterns and trying to apply them to code. While some may be somewhat useful (e.g. “inline hints”), it appears that the context of graphical UI design and its associated patterns does not immediately map to textual code writing. So while some insights can be had, this kind of mapping doesn’t seem to offer great value.

UX Principles in Code

But what if we go deeper?
Can we apply established principles of software-human interaction to code writing?

Take for example clarity. Good user interface designs are clear – at any point in the application they provide the user with an immediate understanding of what just happened, where is the user, what are the options available and their implications and so on. Think breadcrumbs, messages displayed, contextual disabling/enabling of buttons and so on.
What does this mean to code? Saying that “the code needs to be clear” is stating the obvious. Thinking about it from a user (=programmer) experience point of view we should be paying attention to the exact same things:

  • Is it clear to the user where he is from looking at the code?
  • Is the code conducive to understanding the options available at any given point?
  • Are implications of changes communicated clearly?

For example, consider a long file containing a lot of functionality, however related, a file with a lot of definitions, a class with a lot of methods and internal classes, nested callbacks, etc. These are examples of code that does not lend itself immediately to the structure and location in the code. It is harder to follow when reading and especially when debugging it; as debugging often involves jumping from file to file.
Similarly, having too many options to do one thing, e.g. overloaded functions, might introduce some confusion on what is the best way to do things. So there’s a clear tradeoff here between convenience (having the same method name, but with different parameters), and creating a confusing API.

Instead, keeping code listings shorter, tying code artifacts more closely to their location in the code base – e.g. one or two type(s) per file, can help with guiding the user of the code to understand what is the piece of code he is looking at. On the same note, providing one or two ways to do something, e.g. reading from a file or from stream, could actually make it easier for the caller of an API to understand what’s expected and how to work with that API.

Another principle to think about is familiarity and consistency. User interfaces, especially graphical ones, tend to prefer conventional solutions (hence patterns) for common tasks. Icons, links, color coding (red vs. green) are all examples of reusing familiar visual cues to convey meaning and being useful.

Familiarity can apply also to code writing. We can think of several places where this principle is applied:

  • Using common verbs, e.g. names of well known code design patterns
  • Naming getters and setters
  • Consistent naming for classes with similar roles
  • Well used parameter names – i for index, callback for callback functions, onXXX for event handlers
  • Packages following a similar scheme

Using well known patterns for organizing code, naming artifacts, etc. gives the programmer a better chance of understanding and navigating the code. At the project level it might make refactoring easier as it already suggests some code/module structure that can be followed, and may lead to more thoughtfulness with changes that break these familiar patterns.

Efficiency, of course, is also something to look into. Good user interfaces often emphasize the main scenarios supported by making them very efficient for the user. We count clicks, measure how much scrolling is needed, carefully design menus, etc. only to make sure that the common usage scenarios are easy to follow and accessible. In code this may translate to looking at the prevalent scenarios when coding. Readability is of course important, since we mostly read code. But another thing to consider is, for example, debugging and monitoring the running code. Do we insist, for example, on writing one operation per line, with variables defined for intermediate values; or do we cram together several access function calls making it harder to debug and trace the code?

Discouraging Bad Practices with Programmer’s User Experience

Another angle to look into the programmer’s user experience is to try and come with ways where the user experience actually encourages us to write better code.

An example for this is fibonacci indentation where each level of text indentation in the code is indented by a number of spaces matching the fibonacci number at that level. So deeper nesting levels are indented further away. At first, this may seem weird, but when you consider this, you quickly see how this discourages too much nesting – thus improving code readability and the overall experience when dealing with the code.

Another example might be to mandate no empty lines between a variable declaration and where the variable is used. This encourages declaring variables closer to where they are used, keeping related expressions closer visually; otherwise you end up with a big block of code – making it harder to follow.

How is this Useful?

These examples, and some of the conclusions presented here are nothing new to anyone considering the readability and clarity of code. Proper naming, for example, has always been in focus when considering code quality and readability. Still, it might be useful to frame the code readability/usability question as a user experience question, and borrow some practices from the field of user experience design. It helps to reason about better practices for structuring code.

Practically, this could be part of our code reviews, and configured/programmed into our already established set of coding tools – IDEs, linters, static code analysis tools, style guides, etc. The amount of tools available and polyglot nature of today’s software systems, where it’s not uncommon for a system to be coded in several languages, may in fact highlight the value of having a set of overarching principles and insights to guide us to better code writing. We should be able to define and follow principles that can be applied consistently and successfully in several languages at the same time.

One might argue, and justifiably so, that the job of making a programmer’s life easier is handled pretty well with the plethora of tools available, namely modern IDEs. But code can be made better (=easier to work with) by not relying on such mechanisms alone. Besides, not all editors are created equal, and code is viewed in tools other than the original IDE used to write it; e.g. code review tools, diff utilities. And of course, different people use different editors. So editors are very helpful, but I believe we can write clearer code if we don’t necessarily rely on that crutch.

Similarly, some languages also tend to lend themselves better to making code more readable. Type inference and lambda expressions help us make code more succinct and often more readable (though some would argue that explicit typing actually delivers a better experience). The user experience view of code writing is still useful in choosing how to use such language features, where choices are available.

To conclude, considering code writing from a user experience perspective might not be the most natural approach when programming. But if we agree that code readability and clarity is important – directly influencing quality and speed of development – then we should probably look at it from a proven perspective, using considerations and principles otherwise proven for software writing. A programmer’s “code experience” provides another perspective on how code is written and read and should probably be examined when making choices on how to write and structure code. Instead of debating on why a given code is written better this way or that, we can apply user experience guidelines to show us the path to a better code writing.

LiterateJS: Literate Programming with Javascript and HTML

Ever since I started to work on programming languages and models, I was intrigued by the problem of developer productivity. Always looking for effective ways to write and maintain code over time. One of the core issues I constantly struggle with when writing/looking at code is its readability. I generally maintain that the readability of the code has direct impact on its quality, but I digress.

There are all sorts of methodologies and tools to increase code readability, but one of the most interesting ones I came across is the idea of Literate Programming. The idea itself isn’t very new, and was conceived first by Donald Knuth in his book about that same subject.

I don’t claim to explain the idea better than the man who invented it (and I urge the reader to visit the links above to get a better understanding), but the rough idea is to write programs in the form of human-readable text, interspersed with program code. The program code is broken into snippets that are explained by the text. The resulting document is a fully functional (=”compilable”) program, using literate programming tools. It can be executed and it provides results, often embedded in the same document itself.

Being a fan of literature as well as programming, this struck me as a wonderful idea – you get to write your thoughts about what you’re trying to do, in a human readable way, and the code is right there, and it’s executable. There’s no separate documentation or anything – you explain the calculation, along with the code that actually executes it. Often times, the resulting document also contains the result of running the code, maybe even with graphs, images, etc.

There are of course limitations to this. And while I’ve no intention to start a complete debate on the validity of this approach, I will only say that I have my doubts on how this might work for developing a complex system, with several thousands/millions lines of code and a team of developers on it. While it’s theoretically possible to write such systems, I doubt any real benefit would be realized in such a scenario.

Still, for some scenarios, I believe this is a terrific method of writing software. Specifically, when trying to explain complex calculations, and making the calculations repeatable. This is why I think this kind of tools found its sweet spot in academia, where this use case is more prevalent. See iPython notebooks (python) and knitr (for R) as examples.

This is all fun and nice, but I’m not a data scientist, and I don’t delve too often into writing reports.

But then I came across a project at work, which required me to write a small tool to make some calculations, given a set of data. Besides the usual requirements for code quality, one of the prominent requirements was for users of this tool to easily understand the underlying code – the computation leading to the end results, along with intermediate results. And this struck a chord with me.

My first idea was to use R to write the code, both for its applicability as a language to the task and the availability of the knitr package mentioned above. But this was ruled out for reasons of skill set of the intended audience, and other developers who might to base their work on this tool (and also not wanting to install R/shiny to use it).

It was at this point that it came to me that even simple and readily available tools, namely a modern web browser with its javascript engine, are a great fit for the task. After all, today’s browser renders HTML pages with Javascript code running inside it all the time. So I have a presentation language (HTML), with a programming language (Javascript) and the engine to run it, all in one everyday tool – a browser. All that was left was to make it possible to write the tool that will marry both in a way that allows for the executable code to be part of the read document.

So I came up with LiterateJS.

LiterateJS was conceived originally as a proof of concept. I now evolved it to slightly more than that, but it’s no way near a mature project.

Still, it provides a demonstration and the basic facilities to write literate programming document using standard HTML and JS. ‘Standard’ being a key idea here – I intentionally try to avoid doing too much “magic”; instead trying to strike a balance between productivity and usefulness and remaining open to other tools and standards. The examples currently in the project use standard css (bootstrap) with another library for highlighting the code (highlight.js). Resulting in a standard HTML document that can be easily rendered, edited and debugged in standard tools. In this respect this isn’t a classic literate programming tool – there’s no explicit weaving step involved. The javascript code is simply extracted and with some help “injected” into the document, while preserving its highlighting and formatting. The resulting document is standard dynamic HTML document, with the code running in it.

LiterateJS is then a small framework that allows a developer to write literate programs in Javascript and HTML, and distribute them in any way he sees fit. It has a dependency on JQuery but that’s pretty much it (to be honest, the current code, at the time of writing, also depends on bootstrap css classes, but this dependency is planned to be removed).

LiterateJS is still very early in development, and I hope to have the time to continue developing it moving forward (any helpers?). Yet, I don’t expect it to grow too much, and aim to keep it a relatively small tool, with the possibility to add separate extensions later.

I encourage you to try it out, look through the examples and the code, suggest new ideas, features and of course bug fixes. Let me know if you find it useful, and program away!

Pattern Matching in Java?

Writing some code at home, in Java, I came across the problem of trying to compute a value based on the data of another value. This isn’t nothing exciting in on itself, but this whole project I was writing was about trying to write in functional style, as much as possible, in Java 8.
Also, being a fan of fluent interfaces, or readable code in general, this was one of the cases I really missed Scala’s pattern matching capabilities.

So I set to the task of writing a small utility that will allow me to emulate Scala’s pattern matching syntax and behavior, but in Java, at least to some extent.

The end goal I wanted to achieve was to write something similar to:

(you can probably guess the project was something about chess)

In this case p was the parameter passed to a function, which consisted of this call alone. An equivalent piece of code would be to test for the class of p – a series of if-elses, or store this mapping in a map. These are all valid solutions, but I wanted something that would be both concise, and didn’t require extra data preparation. Also something that would be more generally usable than in this case. Besides, I wanted to invent some new way to do this stuff, have some fun doing it.

So I ended up with writing this small utility, which allows for this kind of code:

This code implements a “micro-dsl” of sorts for pattern matching on the data.
The usage of the builder pattern, with 3 internal classes, is to allow for the fluent interface, which was ultimately my goal: enable easy to follow syntax for this kind of operation.

Note that the code makes use of Java 8’s functional interfaces of Predicate and Function, and of course the lambda expression syntax. This allows both for flexibility (you can write any expression you want) as well as concise code.

You can even use it recursively, as the following simple implementation of factorial shows:

It’s not perfect, as it does still tend to be verbose, and not nearly as neat as Scala’s pattern matching, but I believe it does allow for cleaner code, and improves the situation quite a bit for this type of tasks. Note also that this code is pretty simple and self contained – it doesn’t rely on any external library, besides the standard JDK (I did use some trivial utility functions there, e.g. requireNotNull but that’s really beside the point).

Some points where I see this can improve are:

  1. The ability to provide a default match (an “otherwise” case) that will handle all unmatched cases
  2. The ability to provide the data to match as a lazily evaluated function, to allow for optimization (parallel evaluation of the cases?)
  3. A “vectorized” version of this, allowing to specify a pattern match over a complete stream of values, resulting in another stream of values

I will probably do these when I have some more time and the need arises. In the meantime, keeping it simple.

Full source, with updates, is available here.