The concept of storing an algorithm in memory presupposes that the CPU can differentiate between it and the stored data. This is done by associating certain bit patterns (the status of a group of circuits) with specific instructions. This language is literally hard-wired in the machine, and hence is called machine language.
Initially, programmes were written in machine language, i.e. programming was literally a matter of writing sequences of numbers that picked an instruction and a location of data (as with the Difference Engine they were written on punch cards). This is obviously cumbersome, as even quite simple operations consist of huge numbers of built in instructions--the programmer is forced to encode every operation in these small instructions. Moreover, it means that the programme has to be completely rewritten if it is to run on a different machine, as the bit patters corresponding to instructions and memory locations will not be the same.
Since then, programming has developed, so that high-level programming languages allow the programmer to use symbols which (usually) correspond to a whole set of the small hard-wired instructions that the CPU can recognise. This means that the same description of an algorithm can theoretically be used on different machines. However, a program written in such a language cannot run on its own--it must first be translated into the machine language that the computer knows about. This is done by another program, called a compiler, which relates the symbols in the high-level language to (sets of) instructions in the machine language.
A high-level language in theory allows you to write a single program, which can be compiled on two different machines, say A and B. The compiler on A translates the program into A's machine language, and the compiler on B translates it into B's machine language. When the program is run, both A and B execute the same algorithm.
There are two ways of making programs in high-level languages usable. Compilers, introduced above, produce machine language versions of programs. The compiled program is executed as a single unit. There is an alternative to compiling programs, which is to interpret them. Instead of translating the program as a unit, an interpreter translates the individual steps in the high--level program when it is run, so that it appears to be executed exactly as it is written. Interpreted programs run a lot slower than compiled ones. This is because it is necessary to perform an amount of translation for every single step, whereas the compiled program is translated as a whole once and for all. However, interpreters are useful when developing programs, because it is possible to follow the execution to the point where it fails.
<a.von.klopp@bangor.ac.uk>