Programming is not about text

Karolis Masiulis

First of all, what exactly do I mean by that:

  • Programming is creating a data structure that both humans and computers can understand.
  • Text is a 1-dimensional string of symbols.

Between these two definition lies the problem that I want to discuss. Text is perfect for writing down sequential data like a step-by-step instructions for a machine that shuffles 1’s and 0’s. But as we build higher levels of abstractions, we start to realize that…

Some problems are not 1-dimensional

Let’s take an example:

Create a button with a number that starts at 0 and increments the number by one every time the button is clicked.

The button and the number are connected in a loop:

  • The button uses the number and changes the number
  • The number is used by the button and is changed by the button

But because text is 1-dimensional, you can’t display all of this information in a single place — you have to choose either a passive or an active voice. In code this would look something like:

Active voice (React, Vue, etc.)

Button increments the number by one on every click

number = 0---------------------------------button = <button onClick={number +1}> {number} </button>

Remember that these two are usually not in the same place.

By looking at the number:

  • — I can’t see who is using the number and is going to crash if i delete it
  • — I can’t see who and how can change the number

By looking at the button:

  • + I can see the state that the button uses
  • + I can see what the button can change

Passive voice ( Rx, observables, etc.)

Number is incremented by one on every button click

number = startWith(0).onClick(button).scan(number => number + 1).---------------------------------button = <button> {number} </button>

Ignoring the fact that our state is now written in a strange DSL, what we can understand from code has changed:

By looking at the number:

  • — I still can’t see who is using the number
  • + But now I can see who and how can change the number

By looking at the button:

  • + I can still see the state that the button uses
  • — But I no longer see what it can change

This is the fundamental limitation of using a 1-dimensional string to represent a cycle.

No matter how many new JavaScript frameworks come out, it’s not going to get better. They will all have to make a choice between a passive or active voice and limit what’s possible to see in the program.

Testing different JavaScript frameworks

How we got here and what have we missed

This is the definition of programming that I gave at the start:

human <- data structure -> computer

At first, programmers coded in the machine code — a data structure was the same for both sides:

human <- machine code -> computer

Then compilers were developed that could translate any data structure into something that computers can understand:

human <- code -> compiler -> computer

At this point, computers stopped caring about the data structure (as long as it could be translated to the machine code).

But humans didn’t. After all these years one thing has not changed — we are still manipulating the data structure by hand. This makes the programming languages extremely important for our job. And I don’t think it has to be that way.

We need to build a compiler for humans — a tool that would help us manipulate and understand the code in a way that text never could:

human <- compiler <- code -> compiler -> computer

We could stop worrying how our data structure looks and start focusing on what it does. There is nothing magical about text based programming languages, all of them have a limited API. We can build a turing-complete tool that would strip away the noise but still expose a way to use the underlying API.

The logical future of programming

Or at least my best guess

  • There will be a program between a programmer and the code that will indirectly translate user interactions into code. Will that be a chat bot or a visual editor or something else, I don’t know.
  • Bugs will be rare. The editor will not allow creating programs that have bugs. And not by shouting at the programmer like a typical compiler but by preventing a user interaction that would create a bug.
  • Asking questions will give answers. Because we will no longer see the code directly, the editor will have to provide us all the necessary information. No more restrictions created by text as discussed above.
  • Export to whatever. As long as whatever supports most of the features. That means components working both on web, mobile and desktop natively, with no Electron and other bloat. Exporting to a new version of itself wouldn’t be a problem, so no more horror stories like Angular2.
  • Display text where it makes sense. I think that’s what dataflow programming tools got wrong. Text is still the best way to represent step-by-step operations, no need to go crazy with visual stuff.

In my opinion, these ideas are at least worth a try. To put my money where my mouth is I have built a prototype at https://github.com/UgnisSoftware/ugnis (UI is still terrible, you have been warned).

These ideas are not new (Smalltalk, Eve, Elm, Clojure) but I want to encourage more people to think beyond text. And if you ever ask yourself, what would be the best way to represent your program, remember that some problems cannot fit nicely into a 1-dimensional string of symbols.

Karolis Masiulis

Written by

Building software that builds software. Automation, AI, compile-to-JavaScript tools

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade