What a program is
Instructions, state and time — and why a computer is stupider than you expect.
A program is a list of instructions a machine follows exactly, in order, without understanding any of them. That sentence sounds obvious and it is the source of nearly every bug you will write for the next year: the machine did what you said, and what you said was not what you meant.
Instructions, state, and time
Three things are happening in any program, and separating them is most of what learning to program is.
Instructions are the steps: add these, compare those, if this then that. They run one after another, and each one is small — much smaller than a sentence of English.
State is what the program remembers between instructions. A number you worked out on line 3 is still there on line 9 because you put it somewhere and gave it a name. State is the reason a program can do anything more interesting than a calculator with no memory.
Time is the order. withdraw(100) then checkBalance() is a different program from checkBalance() then withdraw(100), and the machine will not warn you that you meant the other one.
balance = 100. A value is put somewhere and given a name. Until this line, nothing named `balance` exists — not zero, not empty. It does not exist.
withdrawn = 60. A second name, a second value. Both are now in the program's memory, and nothing has checked whether this is allowed.
balance -= …. The first change. The old value of balance is gone — not kept, not recoverable. This is what makes order matter: the same instructions in a different order leave different state.
check balance. The check runs, and it runs on the state as it is NOW. Written one line earlier it would have passed. That is the whole reason bugs hide in ORDER rather than in any single line.
= is not equality, and this is the oldest confusion in the subject
Read this and decide what it prints:
int x = 3, y = 8;
x = y; // "make x what y is"
y = x; // "and y what x is"It does not swap them:
before: x=3 y=8
after x=y; y=x: x=8 y=8The 3 is gone. The first line overwrote it, and by the time the second line reads x, there is nothing left of the original value to copy back.
This is the single most studied mistake in learning to program, and the cause is that = looks like the equals sign from mathematics and is not it. In algebra x = y is a claim that two things are equal, and it is symmetric. Here it is an instruction: evaluate the right-hand side, then put the result in the thing on the left. One direction, right to left, and the old value is destroyed.
Which is why this line, meaningless as algebra, is ordinary as an instruction:
i = 5, now i = i + 1 ...
i = 6 (the line that is false as algebra)Students have been confused by i = i + 1 since 1954, when FORTRAN first used = for it. Some languages picked a different symbol — Pascal writes := — precisely because of this.
Swapping needs somewhere to keep the value you are about to overwrite:
int temp = p;
p = q;
q = temp;with a temporary: p=8 q=3The machine is stupider than you expect
Here is a recipe for a human:
Beat two eggs.A person fills in: get eggs from the fridge, take two, find a bowl, crack them, discard the shells, find a fork. Perhaps a dozen decisions, none of them stated.
Here is the same instruction for a machine, and it is still not enough:
OPEN fridge
FIND container labelled "eggs"
IF container is empty THEN ???
TAKE 1 egg
TAKE 1 egg
FIND bowl
IF no bowl THEN ???
CRACK egg over bowlThe two ??? are the interesting part. A human hits an empty fridge and improvises. A machine hits it and stops — or worse, carries on with nothing in its hands and produces an empty bowl that looks like a success.
Every ??? in your head is a decision you must make explicitly. What should happen when the list is empty, when the number is negative, when the network is down? If you do not decide, the language decides for you, and its default is rarely what you wanted.
Why this is a skill and not a subject
You do not learn programming by reading about it, for the same reason you do not learn to swim by reading about it. The knowledge is small; the skill is in applying it when the situation is slightly different from the example.
That is why every lesson here ends with something to do, and why the examples are deliberately a little wrong. Finding out why an example is wrong teaches more than reading a correct one.
What a programming language is for
The instructions a CPU actually executes are numbers. Nobody writes those any more, and nobody should. A programming language is a notation that is:
- precise enough that a machine can turn it into those numbers with no guessing, and
- loose enough that a person can read it and know what it means.
Those two pull against each other, and every language is a position between them. Java sits nearer the precise end than most: it makes you say what type everything is, which is more typing now and fewer surprises later. That trade is the reason Java looks the way it does, and you will feel both halves of it within a week.
Misconceptions
- "The computer made a mistake." Essentially never. It executed your instructions on state you did not expect. The bug is real, and it is in the program or in the assumption.
- "I need to know how a CPU works to program." No. You need to know that the machine follows instructions exactly and remembers only what you tell it to. The rest can come later, and this course does bring you back to it.
- "Good programmers write it right the first time." They write it wrong faster, and find out sooner. Speed of correction beats accuracy of first draft, every time.