Programmers are humans too:
On the design of notations

Steven Pemberton, CWI, Amsterdam

The Author

Contents

ME

ME

= Maine

Apparent Rule

Looking at GA= Georgia, and FL= Florida, it appears that there is no real rule.

Apparent Rule

Looking at GA= Georgia, and FL= Florida, it appears that there is no real rule.

Codes

NE: Nevada or Nebraska?

Codes

NE: Nevada or Nebraska?

It's Nebraska, but NB would have been a better choice

Codes

NE: Nevada or Nebraska?

It's Nebraska, but NB would have been a better choice

MI: Mississippi, Missouri, Michigan, or Minnesota?

Codes

NE: Nevada or Nebraska?

It's Nebraska, but NB would have been a better choice

MI: Mississippi, Missouri, Michigan, or Minnesota?

It's Michigan, but MG would have been a better choice

Codes

NE: Nevada or Nebraska?

It's Nebraska, but NB would have been a better choice

MI: Mississippi, Missouri, Michigan, or Minnesota?

It's Michigan, but MG would have been a better choice

MS: Mississippi, Missouri, or Minnesota?

Codes

NE: Nevada or Nebraska?

It's Nebraska, but NB would have been a better choice

MI: Mississippi, Missouri, Michigan, or Minnesota?

It's Michigan, but MG would have been a better choice

MS: Mississippi, Missouri, or Minnesota?

It's Mississippi, but MP would have been a better choice.

Active and Passive

But solving these problems with reading 2-letter codes would still not solve the problem of writing them: your passive and active abilities are different.

Doing it better

I couldn't believe it wasn't possible to do the 2-letter codes better.

So I wrote a program (in ABC as it happens; more on that later).

The best rule I came up with:

The point

My point here is that the 2-letter codes were introduced because of automation.

But that is no excuse for ignoring the needs of people.

Usability

Usability is about designing things (software/programming languages/cookers) to allow people to do their work:

Efficient, Error-free, Enjoyable or
Fast, Faultless and Fun

HCI

A problem is that the people designing things are usually not the people who will be using those things, and yet they tend to design for themselves.

So... you have to use HCI techniques:

Notations

Few talk about the usability of notations.

Yet the design of notations affects what you can do with them.

Numbers

For instance, Roman numerals:

Homework

I was helping my children with their maths homework, and a question arose for me:

Why do they make things so difficult?

So I went back to first principles.

What would mathematical notation look like if it were designed with consistency and usability in mind?

Warning

What follows was more than a year's work, using reams of paper. It is hard work making things simple.

When you achieve a final simple result, it often looks so obvious that it hard to appreciate how difficult it was to get there.

As a colleague who designs program interfaces remarked: "When you succeed in making an interface as easy to use as a coffee machine, they treat you like a plumber"

I'm only going to show you the tip of the iceberg here.

It resulted in a monograph that I wrote for my sons' birthdays. You can read it here: Numbers.

Declarative

Before I show the details, let me remind you of the difference between procedural and declarative approaches.

The first declarative definition

Procedural approaches describe how to achieve something.

Declarative approaches describe what to achieve.

In school you learn procedurally how to add, subtract, multiply and divide, and then you are told

The square root of a number is another number that when you multiply it by itself, gives you the original number.

This doesn't tell you how to calculate the square root; but no problem, because we have machines to do that for us.

Procedural code

function f a: {
    x ← a
    x' ← (a + 1) ÷ 2
    epsilon ← 1.19209290e-07
    while abs(x − x') > epsilon × x: {
        x ← x'
        x' ← ((a ÷ x') + x') ÷ 2
    }
    return x'
}

This is why documentation is so essential in procedural programming, because the distance between the description of the problem space and the code is so great.

Mathematical Notation

We have addition:

a+b

You can define subtraction as

(a+b) − b = a

This is a declarative definition. It tells you the what but not the how.

Monadic −

There is also a monadic version of −, which can be defined as:

−a = 0−a

Where 0 is the identity for addition, since

a+0 = a

Multiplication

Multiplication is at its heart repeated addition:

a × 3 = a + a + a

and it also has an identity value:

a×1 = a

Its complement is division, defined in the same way as subtraction:

(a×b) ÷ b = a

(I use ÷ instead of / because when user-testing with my target audience, they said "Please use the same symbols as on a calculator")

Monadic divide

Notably, there is no monadic version of divide. But if we define it using the same pattern:

÷a = 1 ÷ a

something surprising happens: identities that we know from the lower level have exactly the same form as ones at this higher level. For instance:

Identities

−−a = a
÷÷a = a

Identities

a−−b = a + b
a÷÷b = a × b

Identities

−(a−b) = (b−a)
÷(a÷b) = (b÷a)

Up another level

Just as multiplication is repeated addition, raising to the power is repeated multiplication:

a↑3 = a × a × a

So we can define its complement in the same way:

(a↑b)↓b = a

This is of course what we know of as root, where x↓y traditionally, and weirdly, is notated

y√x

So if ↑ is a higher version of multiplication, then ↓ is just a higher version of division.

The point

Defining it in this way suddenly exposes literally dozens of well known identities that have a similar form to identities at the two lower levels!

Just to pick a couple out:

Identities 1

a×(−b) = −(a×b)

Identities 1

a×(−b) = −(a×b)
a↑(−b) =  ÷(a↑b)

Identities 1

a×(−b) = −(a×b)
a↑(−b) =  ÷(a↑b)

          (a−b = 1/ab)

Identities 2

a×(÷b) = a÷b

Identities 2

a×(÷b) = a÷b
a↑(÷b) = a↓b

(I consider this so beautiful, that even if this had been the only result, the whole exercise would have been worth it!)

Identities 2

a×(÷b) = a÷b
a↑(÷b) = a↓b

               (a1/b = b√a)

Why is this notation better?

a+2 = 4
a = 4−2

a×2 = 4
a = 4÷2

a↑2 = 4
a = 4↓2

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Also pretend, just for a moment, that their chief method of communicating with a computer was with programming languages.

Programmers are possibly human too

Imagine, hypothetically, that programmers are humans...despite all evidence to the contrary:

Also pretend, just for a moment, that their chief method of communicating with a computer was with programming languages.

What should you do?

ABC

We designed a programming language: ABC

We used HCI principles:

ABC: results

A procedural language with only 5 very high-level data types.

Our biggest take aways:

ABC: results

ABC: results

ABC: results

ABC: results

ABC: results

Many cryptographic algorithms in use today were designed with ABC

ABC went on to form the basis of Python.

TAXATA

In building a programming environment for ABC, we developed a concept that was a stronger version of WYSIWYG, that we called TAXATA: Things are exactly as they appear

We built a system (Views) that made this principle the central element of the design: if you changed something (edited it) the system changed itself to match.

I demo'd this at CHI 91.

In New Orleans!

Views

A screen dump of Views running in 1993

This system had an extensible markup language, vector graphics, style sheets, a DOM, client-side scripting ... today you would call it a browser (it didn't use TCP/IP though).

It ran on an Atari ST (amongst others).

This work led me to get involved with the World Wide Web at W3C, co-designing HTML, XHTML, CSS, and a bunch of other technologies.

Declarative programming

The Views system client-side programming language was a first attempt at defining a declarative programming language.

We saw that it gave you immense power, and ease of use at the same time.

So let me talk about the principles.

1957: The 1st municipal computer (Norwich, UK)

The First Computer in Norwich

Just one of 21 cabinets making up the computer.

2015: The Raspberry Pi Zero

Raspberry Pi in Norwich

The first computer so cheap that they gave it away on the cover of a magazine

How do they compare?

The Elliot ran for about a decade, 24 hours a day.

How long do you think it would take the Raspberry Pi Zero to duplicate that amount of computing?

How do they compare?

The Elliot ran for about a decade, 24 hours a day.

How long do you think it would take the Raspberry Pi Zero to duplicate that amount of computing?

The Raspberry Pi Zero is about one million times faster...

Compare

The Raspberry Pi is not only one million times faster. It is also one millionth the price.

A factor of a million million.

A terabyte is a million million bytes: nowadays we talk in terms of very large numbers.

Want to guess how long a million million seconds is?

Compare

The Raspberry Pi is not only one million times faster. It is also one millionth the price.

A factor of a million million.

A terabyte is a million million bytes: nowadays we talk in terms of very large numbers.

Want to guess how long a million million seconds is?

30,000 years...

A really big number...

Moore's Law

In fact a million million times improvement is about what you would expect from Moore's Law over 58 years.

Except: the Raspberry Pi is two million times smaller as well, so it is much better than even that.

Pricing of new technology

When a new technology is introduced, it is often priced not on what it costs to produce, but on what it would cost to do the same with the technology it is replacing.

For example, when Edison first introduced electric light into homes, electricity was priced based on what it would cost to produce the same amount of light by traditional means, but now with additional benefits of instant light, and no flames.

Similarly, early computers were priced based on what it would cost to do the same amount of computation using people.

1957

In the 50's, computers were so expensive that nearly no one bought them, but leased them.

To rent time on a computer then would cost you of the order of $1000 per hour: several times the annual salary of a programmer!

When you leased a computer you would get programmers for free to go with it.

Compared to the cost of a computer, a programmer was almost free.

The design of programming languages

The first programming languages were designed in the 50s:

Cobol, Fortran, Algol, Lisp.

They were designed with that economic relationship of computer and programmer in mind.

It was much cheaper to let the programmer spend lots of time producing a program than to let the computer do some of the work for you.

Programming languages were designed so that you tell the computer exactly what to do, in its terms, not what you want to achieve in yours.

Back to now

It happened slowly, almost unnoticed, but nowadays we have the exact opposite position:

Compared to the cost of a programmer, a computer is almost free.

I call this Moore's Switch.

Moore's Switch

Moore's Switch illustrated
Relative costs of computers and programmers, 1957-now

But, we are still programming in programming languages that are direct descendants of the languages designed in the 1950's!

We are still telling the computers what to do.

Declarative programming

A new way of programming: declarative programming.

This describes what you want to achieve, but not how to achieve it..

Let me give some examples

A Procedural Clock

A clock in C, 1000+ lines

1000 lines, almost all of it administrative. Only 2 or 3 lines have anything to do with telling the time.

And this was the smallest example I could find. The largest was more than 4000 lines.

A Declarative Clock

type clock = (h, m, s)
displayed as 
   circled(combined(hhand; mhand; shand; decor))
   shand = line(slength) rotated (s × 6)
   mhand = line(mlength) rotated (m × 6)
   hhand = line(hlength) rotated (h × 30 + m ÷ 2)
   decor = ...
   slength = ...
   ...
clock c
c.s = system:seconds mod 60
c.m = (system:seconds div 60) mod 60
c.h = (system:seconds div 3600) mod 24

A Running Declarative Clock

The Views System

XForms

XForms is a declarative system for defining applications. BBC Sport App

It is a W3C standard, and in worldwide use.

Example: 150 person years becomes 10!

A certain company makes one-off BIG machines (walk in): user interface is very demanding — traditionally needed:

5 years, 30 people.

With XForms this became:

1 year, 10 people.

Do the sums. Assume one person costs 100k a year. Then this has gone from a 15M cost to a 1M cost. They have saved 14 million! (And 4 years)

Example: Insurance Industry

Manager: I want you to come back to me in 2 days with estimates of how long it will take your teams to make the application.

Example: Insurance Industry

Manager: I want you to come back to me in 2 days with estimates of how long it will take your teams to make the application.

[Two days later]

Programmer: I'll need 30 days to work out how long it will take to program it.

Example: Insurance Industry

Manager: I want you to come back to me in 2 days with estimates of how long it will take your teams to make the application.

[Two days later]

Programmer: I'll need 30 days to work out how long it will take to program it.

XFormser: It's already running.

Example: NHS

The British National Health Service started a project for a health records system.

Example: NHS

The British National Health Service started a project for a health records system.

One person then created a system using XForms.

State

XForms is all about state. (Which means it meshes well with REST - Representational State Transfer).

Initially the system is in a state of stasis.

When a value changes, by whatever means, the system updates related values to bring it back to stasis.

This is like spreadsheets, but much more general.

The result is: programming is much easier, since the system does all the administrative work for you.

Clock

; SourceArticle

Example

I've got a position in the world as x and y coordinates, and I want to display the map tile of that location at a certain zoom.

My data:

x, y, zoom

Openstreetmap has a REST interface for getting such a thing:

http://openstreetmap.org/<zoom>/<x>/<y>.png

Map interface

However, the Openstreetmap coordinate system changes at each level of zoom.

As you zoom out, there are in each axis half as many tiles, so there are ¼ as many tiles. And the interface indexes tiles, not locations.

So to get a tile:

Declarative Example

The data: x, y, zoom

scale = 226 - zoom
tilex = floor(x/scale)
tiley = floor(y/scale)
url = concat("http://tile.openstreetmap.org/", zoom, "/", tilex, "/", tiley, ".png")

That is really all that is needed (modulo syntax, which looks like this:)

<bind ref="tilex" calculate="floor(../x div ../scale)"/>

That's the form. Now the content:

<input ref="zoom" label="zoom"/>
<input ref="x" label="x"/>
<input ref="y" label="y"/>
<output ref="url" mediatype="image/*"/>

and the tile will be updated each time any of the values change.

Live tile with zoom

Source

Map

Source

Map

; SourceArticle

Conclusion (programming)

For historical reasons, present programming languages are at the wrong level of abstraction: they don't describe the problem, but only one particular solution.

Declarative programming allows programmers to be ten times more productive: what you now write in a week, would take a morning; what now takes a month would take a couple of days.

Once project managers realise they can save 90% on programming costs, they will switch to declarative programming.

I believe that eventually everyone will program declaratively: fewer errors, more time, more productivity.

Conclusion (notations)

Notations are a greatly overlooked issue in the field of usability.

Good notations have all the features of good interaction designs:

Thank you!