Chapter One in a very personal history of programming
In the Beginning
…there were no programmers, because the computers were the program. They did not really resemble modern computers in any way. They weighed tons and took up whole walls in rooms with custom-built air conditioning and ventilation for their relays and tubes, not to mention specially reinforced floors.
Long before I learned how to program; in fact, quite a long time before I was born, the first computers were “programmed” by flipping electro-mechanical switches and plugging in wires on a patch panel.
The people (wearing lab coats) who operated these computers didn’t even think of the plugging and switch flipping as programming. The program was designed by electrical engineers and built into the wiring of these incredibly expensive giant electric calculators. What these people were doing was entering the problem to be calculated.
The photo below is often mis-labeled Programming the ENAIC computer. The fact is that like all other computers of its time, ENIAC was not programmable. At least not in the sense that one thinks of. It was programmable like a VCR, or a digital watch (for us old timers). What made it special however, was that instead of having just one program hardwired into it, it had many. Each one of the panels you see in the photo below was one hardwired program. Using the patch cables computer operators such as those in the photo could enter data into the panel that contained the hardware “program” to be run, and configure the panels together to run one program/panel from the results of another.
I do not mean to trivialize the work. It required a great deal of creativity and expertise, and was ground breaking in its own right. However, it simply was not programming as most people understand the term. It was more aking to electrical engineering.
Although Konrad Zuse¹ is now recognized as having invented the modern computer and the first programming language in Nazi Germany, his efforts remained top secret for a long time. The thing that really launched software programming as we know it today else was the publication of the First Draft of a Report on the EDVAC² in 1945, written (or perhaps more accurately: assembled and edited) at the request of the U.S. Army by John Von Neumann, a remarkable fellow, with too many achievements to list here. The paper described the basis for modern computers as we know them; very fast binary calculators that store programs in machine language and execute them. The really innovative part was that the computer he described wasn’t hardwired for any programs. Programs had to be written using opcodes (which I will describe below). Circulation of this report is undeniably the catalyst for modern computer design.
In 1949 EDVAC ran its first program, read from a gigantic roll of magnetic tape. The tape spools were so massive that women like my mother were discouraged from entering the field for fear it was not possible for a woman to physically transport them to and from the computer.
It was 1949:
- Harry Truman became president and introduced his Fair Deal
- It was the first year in which no African-American was reported lynched in the United States of America
- Canadians and Australians broke free of the commonwealth and created their own citizenships
- Mao and the People’s Republic of China took power
- Israel held its first election and joined the UN
- The German Democratic Republic was established
- NATO was formed
- Winston Churchill proposed the European Union
- The first non-stop around-the-world airplane flight happened
- The first jet powered airplane flew
- The Soviet Union tested its first atomic bomb…
And programming was born.
“Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1(and)1/2 tons.”
~ Popular Mechanics, March 1949
Then there was the word
“Von Neumann” computers, as modern computers are sometimes called, all operate on some basic shared principles. They have memory divided into two “spaces” called the stack and the heap. The heap is used to store the running program, and the stack is used to store the data that is the input and output. As you will see later, some clever programmers play tricks, hiding data within code, or code within data.
The binary³ program is stored in the heap as a series of hexadecimal words.⁴ Words are different lengths on different CPUs. Very old CPUs used 8-bit words, modern CPUs use 64-bit words. Each word triggers a specific CPU operation. For this reason, they are called opcodes. For example, on an old 16-bit Intel CPU, the hexadecimal number “2104” will store the number from stack location 104 in the CPU in a special memory scratchpad called a register. “1105” will add the number from stack location 105 to the first number and “3106” will take the result and store it in stack location 106. All computer programs eventually come down to a series of words stored in memory.
In assembly language, a three-letter mnemonic represents the binary or hexadecimal machine instruction. For almost a decade, programmers used assembly language to locate and retrieve data in memory and move it to the Central Processing Unit (CPU) for computation. The step by step instructions do not really resemble normal human logic in any way.
Below is a very simple program that adds two numbers. I show the binary, the hex, and the assembly instructions side by side (the data is not shown).
Here is a simple assembly language program that prints out the phrase “Hello World”. The first words on lines 5–9 are examples of opcodes (there are other opcodes in this program that are not as easily pointed out).
1 section .text
2 global _start
4 ; write our string to stdout.
5 mov edx,len ; third arg: message length
6 mov ecx,msg ; second arg: pointer to msg
7 mov ebx,1 ; first arg: file handle (stdout)
8 mov eax,4 ; system call number (sys_write)
9 int 0x80 ; call kernel
10 ; and exit.
11 ebx,0 ; first syscall argument: exit code.
12 mov eax,1 ; system call number (sys_exit)
13 int 0x80 ; call kernel.
14 section .data
15 msg db “Hello, world!”,0xa ; the string to print.
16 len equ $ — msg ; length of the string.
This kind of programming is called bare metal programming.⁵ It is terse and difficult to understand. In those early days, computer programs were small because the capacity of computers was small.
The cellphone that you likely have in your pocket has 30 million times more storage and is about 10 million times faster than an IBM 650 was in 1954. The smallest program on your cell phone would not fit on 10,000 IBM 650s wired together. The phone hardware is also about 40,000 times smaller and lighter, uses about 400,000 times less power, and is 10,000 times less expensive. The IBM 650 cost half a million dollars in 1954 which is equal to about 4.6M today.
For the rest of this series, I will describe the technological advances that allowed programmers to evolve ever larger and increasingly more complex programs, starting with the first programming languages.
 For those who are interested, I am in the process of writing an appendix that contains a list of all the people I mention, along with basic biographical information. I will publish it at the end of the last article in the series.
 Von Neumann, John. “First Draft Of A Report On The EDVAC”. 1945, Moore School Of Electrical Engineering, University Of Pennsylvania, doi:10.5479/sil.538961.39088011475779.
 Whereas our familiar counting system is base 10 and binary is just base 2, a hexadecimal system is base 16.
This article is an excerpt from my upcoming book The Chaos Factory which explains why most companies and government can’t write software that “just works”, and how it can be fixed.