This isn’t machine code. From the perspective of the machine, it’s extremely high-level programming. Yet it’s hardly natural language. There are weird punctuation marks. Cryptic abbreviations. Repeated nesting. And two languages: JavaScript awkwardly embedded within Bash.

Bret Victor gives this concise definition of programming:

Programming is blindly manipulating symbols.

By “blindly”, he means we can’t see the results of our manipulation. We can edit a program, re-run it, and diff the output, but programs are complex and dynamic, so this is neither a direct nor an immediate observation of our edit. By “symbols”, he means we don’t manipulate the output of our program directly but instead work in abstractions. These abstractions may be powerful, but they can also be difficult to grasp. In Donald Norman’s terms, these are the gulf of evaluation and the gulf of execution.

But clearly some code is easier to understand than others. One symptom of inhuman code is spaghetti: code that lacks structure or modularity; where in order to understand one part of a program you have to understand the entirety of it. This is frequently caused by shared mutable state. When a piece of state is modified by multiple parts of a program, it is much harder to reason about its value.

Indeed, how do we know what a program does? If we can’t track its complete runtime state in our heads, reading code is insufficient. We use logs, debuggers, and tests, but these tools are limited. A debugger, for example, can only show a few values at a single moment in time. We continue to have great difficulty understanding code, and it can feel like a miracle that anything works at all.

Despite these challenges, we’re still writing code, for myriad applications, more than ever before. Why? Are we masochists? (Maybe.) Are we unable to change? (In part.) Is there no better solution?

In general — and that is the critical qualifier — no. Code is often the best tool we have because it is the most general tool we have; code has almost unlimited expressiveness. Alternatives to code, as well as higher-level programming interfaces and languages, do well in specific domains. But these alternatives must sacrifice generality to offer greater efficiency within their domain.

If you can’t constrain the domain, it’s unlikely you’ll find a viable replacement for code. There is no universal replacement, at least not while humans primarily think and communicate through language. And it’s hard to constrain the domain of science. Science is fundamental: to study the world, to extract meaning from empirical observations, to simulate systems, to communicate quantitative results.

A medium to support discovery must be capable of expressing novel thought. Just as we don’t use phrasal templates for composing the written word, we can’t be limited to chart templates for visualization or a drop-down of formulas for statistical analysis. We need more than configuration. We need the composition of primitives into creations of our own design.

If our goal is to help people gain insight from observation, we must consider the problem of how people code. Victor had the following to say about math, but it applies equally to code:

The power to understand and predict the quantities of the world should not be restricted to those with a freakish knack for manipulating abstract symbols.

Improving the human experience of coding is not just about making your workflow more convenient or efficient. It empowers people to better understand their world.

Introducing d3.express

If we can’t eliminate coding, can we at least make it easier for humans, with our sausage fingers and finite-sized brains?

To explore this question I am building an integrated discovery environment called d3.express. It’s for exploratory data analysis, for understanding systems and algorithms, for teaching and sharing techniques in code, and for sharing interactive visual explanations. To make visualization easier—to make discovery easier—we first need to make coding easier.

I cannot pretend to make coding easy. The ideas we wish to express, explore and explain may be irreducibly complex. But by reducing the cognitive burden of coding, we can make the analysis of quantitative phenomena accessible to a wider audience.