In basic terms the difference between an interpreter and a compiler is the point at which a source text is actually executed.
An interpreter interprets a language by reading the text or source code and then performing computations as it processes the text to execute the text. So as the interpreter is reading the source of the program, the program runs or executes as the interpreter reads lines of code and performs those actions.
A compiler compiles a language by reading the text or source and transforms the source code into another form which is typically machine code.
To make things a bit more complicated you will see that some interpreters have a Just In Time (JIT) compiler component to them. So the process then is the interpreter reads the source code and converts it to an intermediate, more machine friendly, form which is then fed to a JIT compiler which creates a machine code which is then executed by the target hardware. Most interpreters of this form have a Virtual Machine which is hardware independent that uses a JIT compiler to target the actual hardware when the program is executing. The Virtual Machine is hardware independent but the JIT compiler must be tailored to the particular hardware. The JIT compiler compiles the Virtual Machine code or instructions into the target hardware machine code which is then executed by the hardware.
And by the way this kind of Virtual Machine is different from the virtual machine used with Docker and other types of containers which has hardware virtual machine support. The Virtual Machine used by these interpreters is an application which emulates some abstract hardware.
For examples of this kind of Virtual Machine look to the Java Virtual Machine. Or the Python Virtual Machine. See Java “Virtual Machine” vs. Python “Interpreter” parlance?
.
And this document, Python (2.5) Virtual Machine: a guided tour has some of the gritty details about the Python Virtual Machine though an older version of Python.
A compiler will normally compile the source text to actual hardware machine language. So the output of a compiler depends on the actual target hardware. The machine code of a compiler that targets an x86 architecture is different from one that targets an ARM architecture.
Using a compiler will require additional software tools as the process for a compiler is generally something like the following:
- create the source code file or files
- compile the source code file or files to generate one or more object code files
- link the object code files with various libraries to generate an executable
- run the executable application
Using an interpreter will be a simpler procedure something like the following:
- create the source code file or files
- execute the interpreter program, specifying the source code file
The C programming language is normally a compiled language using a compiler. The python programming language is normally an interpreted language using an interpreter.
However there is nothing to stop someone from writing a compiler for what is normally an interpreted language nor writing an interpreter for what is normally a compiled language. And you can see examples of this all over the internet.
To make things even a bit more complicated in the naming of things, there are applications called compilers that translates one programming language into another.
A classic example is the first C++ compilers which would transform C++ source code into C source code and then compile the C source code into machine language. It's not done like that anymore and the C++ language was a subset of modern C++ (C++11/17) but it worked for a proof of concept.
I have also seen a translator that would transform C source code into JavaScript.