Software approachability outweighs everything else

When considering the set of tools to use for a particular software project, I usually have an overriding urge to make the "best" decision. What constitutes best? Ultimately I need to make a correct decision amongst the following set of tradeoffs.

  1. Time - How long does it take to implement the solution?
  2. Familiarity - How familiar are you with the tooling?
  3. Testability - How is the solution going to be tested?
  4. Maturity - How developed is the larger community around the chosen solution?
  5. Maintainability - How long is it reasonable to expect this solution to continue to work?

It really doesn't matter if you are trying to select a programming language, a framework, a library, or all of the above. What you really want to do is make sure the tools you chose provide you with enough advantages to cover the cost of any headaches they also introduce. Different projects with different goals should place a different emphasis on the points I've listed out above. A one-off script to move some data around does not care about maintainability at all. A rewrite of a microservice would put a signficant emphasis on maintainability, otherwise you might want to reconsider why you need to do a rewrite. From here forward I'm just going to call these the "5 points".

Given perfect knowledge of the available options, you could just draw up a huge list of everything you know and then choose the best option. If you were exceptionally motivated you could assign some score on a scale of 1 to 100 for each solution. Then you simply select the one with the highest score. Real world problems and the decisions made to solve them do not play out anything like this.

In the real world, we don't have perfect knowledge of any platform. The best knowledge we have is that of of the plaforms we're familiar with from past projects. I've worked on at least one project where some non-trivial component is implemented in some language used nowhere else. The usual explanation given is something like "Bob was told to get this done and Bob knew Java. So he wrote it in Java". This doesn't imply anything about Bob, other than the fact that he was confident getting things done in Java.

Such a state of mind obviously biases us to using the tools we already know. If something worked in the past, that thing probably will work again. But at some point you eventually come across a project that those tools simply are not the right fit for. I already indicated this in my second point "Familiarity". But you can still take some existing knowledge and use it in the consideration of something you don't know much about yet. For example, an experienced Java developer might find Scala higly approachable because existing Java libraries are still accessible from Scala.

I've made this decision enough times to realize the actual factor that leads to me a conclusion isn't the 5 points themselves, it is the approachability of the chosen tools. If a set of tools is approachable, then I can learn what I want to know about them quickly enough to determine where each one scores on the 5 points. My personal form of learning is some form of experiential learning. Simply put, I value my own hands-on experience and judgement with a piece of software much more than anything touted by a white paper. If you consider the problem of no-one having perfect knowledge about any tools, my theory is any informed decision relies on the results of someone's hands-on experience.

The downside to this is that getting hands-on experience with anything does in course involve a time comittment. In 2020, the number of tools I have available to myself for-free or at zero-cost is staggering. I am extremely unlikely to spend my time evaluating anything that makes it difficult to do so.

To put approachability in perspective, I am a Python advocate. I am a Python advocate first and foremost because of the help function that comes builtin to Python. You can use the builtin help function from the Python REPL to access the documentation of anything.

$ python3.7
Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> help(print)
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

In the above example, I am able to start the Python REPL by just typing python3.7 and then I am immediately able to access the documentation of the print function just by running help(print). This lets me quickly learn more about anything, provided the author took the time to write some documentation. When I am ready to try something out, I'm already in the REPL and can do so.

You can compare this with the C programming language, which lacks a REPL entirely. To learn about the simplest way to print something, you would need to consult some reference material. If you're running an even somewhat modern Linux machine, you could also just type man 3 printf in any shell and get a manual page for the printf function. If you have TCC installed you can make a script like this

#!/usr/bin/tcc -run
#include <stdio.h>
int main() {
  printf("%s", "Hello blog readers!\n");
}

It can then be run like any other script without any special knowledge of C compilers.

$ ./hello_world_tcc.c 
Hello blog readers!

But realistically, would you want to spend your available time studying the C-language standardized specification and its format strings or would you prefer Python's print("Hello")? I only really know about TCC because of my experience with C. Actually writing, compiling, and executing a normal project in C involves lots of steps usually wrapped up in a Makefile. This of course is a contrived example. Someone evaluating programming languages, frameworks, & libraries doesn't really stumble when trying to print a string.

This simple example frames the real context when considering real-world problems. To reach a conclusion about a tool, you need some amount of time actually spent experimenting with that tool. If I start with a list of 8 tools to consider, I quickly skip over any tool that does not make it painfully simple to try things out. Only after exhausting all other options would I come back and then make a large time investment to evaluate it. I simply don't have the time to commit upfront if there is even a possibility that something else is easier to work with.

Summary

I envisioned a very large section here explaining what makes something approachable. I ultimately realized it is somewhat unique for everyone. I'd also kind of be missing my own point if a simple concept somehow needed 10 or 12 paragraphs just to relate to the reader.

So in summary, if you want your software to be popular make sure it is approachable. It's great if is also performant, or any of the other things you think are important. But if you want adoption, approachability comes first. If you are considering a piece of software don't waste your time with something that is difficult to even get started with.

Of course, the inverse of this can also be applied as well. If the software you're selling is a pile of garbage be sure and obscure it behind as many layers of misdirection and misinformation as possible. Make sure that no one can find out the real truth of it until they're committed, preferably in the form of paying you money.

Addendum: The subject of operability

I'm sure some reader of my 5 points would like to make the objection that something like "operability" isn't listed. There is a legitimate concern that in the future software must continue to function by someone who simply doesn't have the time to understand every detail of the underlying system. They just need to get it up and running, then keep it running. This is really just an aspect of maintainability. Software needs to be written with these concerns in mind, starting with the selection of appropriate tools. Powershell is probably a reasonable choice for a build script on Microsoft Windows, but is a less than ideal solution for an application web server running entirely on Linux.


Copyright Eric Urban 2020, or the respective entity where indicated