Digitale Computer verstehen nicht die Sprachen, die Menschen sprechen. Der Maschinencode besteht aus einer Folge von einfachen Computeranweisungen, wobei jede Anweisung als eine Folge von binären Ziffern oder Bits (d. h. 1 und 0) ausgedrückt wird. Verschiedene Computer „sprechen“ oder „verstehen“ typischerweise verschiedene Maschinensprachen. So kann ein Computer die ADD-Operation als 10011111
darstellen, während ein anderer die gleichen Operationen als 000110
darstellt. Nicht nur die Bitmuster unterscheiden sich in der Regel von einem Computer zum anderen, sondern auch die Anzahl der Bits, die zur Darstellung einer Operation verwendet werden, kann unterschiedlich sein.
Wenn ein Programm ausgeführt wird, fungiert das Betriebssystem (z. B. Windows, Linux, OS X usw.) als Host-Umgebung, die dem Programm Dienste zur Verfügung stellt, z. B. den Zugriff auf Tastatur, Bildschirm und Festplatten. Leider ist auch die Art und Weise, wie das Programm auf diese Dienste zugreift, von Betriebssystem zu Betriebssystem unterschiedlich. Aufgrund der Unterschiede zwischen den Maschinensprachen und den Anforderungen des Betriebssystems sind in Maschinensprache geschriebene Programme mehr auf das System ausgerichtet, auf dem das Programm läuft, als darauf, wie das Programm ein Problem löst. Außerdem bedeutet dies, dass es nicht möglich ist, Maschinencode zwischen verschiedenen Computern auszutauschen, ohne eine Art Übersetzungsdienst bereitzustellen – in der Regel in Form einer virtuellen Maschine.
Das Schreiben von Programmen in Maschinensprache ist langsam, mühsam und fehleranfällig. Die Lösung bestand darin, höhere Programmiersprachen zu entwickeln, die sich mehr auf das Problem und weniger auf das System (die Hardware und das Betriebssystem) konzentrieren, auf dem das Programm läuft (siehe Abbildung 2). Aber Computer führen in der Regel keine Programme aus, die in Hochsprachen geschrieben wurden, also muss es eine Möglichkeit geben, ein in einer Hochsprache geschriebenes Programm in Maschinensprache zu übersetzen. Zwei Arten von Computerprogrammen führen die notwendige Übersetzung durch: Compiler und Interpreter.
Ein Compiler ist ein Programm, das andere Programme, die in einer Hochsprache wie C oder C++ geschrieben wurden, in Maschinencode oder Maschinensprache übersetzt.
Andere Sprachen wie Java und C# nehmen einen anderen Weg: In diesen Sprachen geschriebene Programme werden in eine Zwischendarstellung kompiliert (eine Darstellung, die irgendwo zwischen der Hochsprache und der Maschinensprache liegt), die oft als virtueller Maschinencode bezeichnet wird. Der Code der virtuellen Maschine wird dann zur Eingabe für ein anderes Programm, den Interpreter oder die virtuelle Maschine (VM, ein Programm, das eine Hardware-CPU simuliert). Einige Sprachen, wie z. B. Javascript und Perl, sind vollständig interpretiert, d. h. sie werden nicht kompiliert, sondern direkt interpretiert.
Jeder Ansatz zur Ausführung eines in einer höheren Programmiersprache geschriebenen Programms hat Vor- und Nachteile. Programme, die in vollständig kompilierten Sprachen (z. B. C und C++) geschrieben wurden, werden schneller ausgeführt als Programme, die in teilweise kompilierten Sprachen (z. B. Java und C#) geschrieben wurden, und sie werden viel schneller ausgeführt als Programme, die in vollständig interpretierten Sprachen (z. B. Javascript und Perl) geschrieben wurden. Um den Leistungsunterschied zu verdeutlichen, sei angenommen, dass ein C++-Programm nach der Kompilierung in der Zeit von 1,0 ausgeführt wird. Ein entsprechendes Programm, das in einer kompilierten und dann interpretierten Sprache geschrieben wurde, wird im Allgemeinen in 3 bis 10 Minuten ausgeführt. Das gleiche Programm, das in einer rein interpretierten Sprache ausgeführt wird, läuft in einer Zeit von etwa 100. Aktuelle Implementierungen der Java- und C#-VMs verwenden einen Just-in-Time-Interpreter (JIT), der einen Teil des virtuellen Codes während der Verarbeitung in Maschinencode kompiliert. JIT-Prozessoren reduzieren die Laufzeit auf etwa das 1,5-fache der Laufzeit rein kompilierter Sprachsysteme. Die Programmiersprache Python ist ein wenig anders: Der Hauptteil eines Python-Programms wird interpretiert, ist aber relativ klein und hat daher nur minimale Auswirkungen auf die Gesamtlaufzeit. Die meisten Python-Bibliotheken, in denen das Programm die meiste Zeit verbringt, sind in C geschrieben, so dass Python-Programme fast so schnell laufen wie ein entsprechendes C-Programm.
Andererseits können die ausführbaren Programme, die von einem reinen Compiler erzeugt werden, nicht zwischen verschiedenen Plattformen übertragen werden (z. B. können Sie ein Windows-Programm nicht auf einem Apple-Computer ausführen), während in interpretierten Sprachen geschriebene Programme leichter zwischen verschiedenen Computern übertragen werden können. Diese Übertragbarkeit wird durch die Bereitstellung einer VM oder eines Interpreters für jede Plattform (Kombination aus Hardware und Betriebssystem) erreicht. Interpreter und VMs sind Programme, die in rein kompilierten Sprachen geschrieben sind. Sie sind also nicht portabel, aber die Programme, die sie verarbeiten, sind es.