Hier werden viele Fragen zu interpretierten und kompilierten Sprachwerkzeugen gestellt. Ich frage mich, ob die Unterscheidung überhaupt Sinn macht. (Eigentlich handelt es sich bei den Fragen in der Regel um Sprachen, aber sie denken wirklich über die beliebtesten Implementierungen dieser Sprachen nach.)
Heute wird fast keine Implementierung streng interpretiert. Das heißt, so gut wie niemand parst und führt den Code zeilenweise aus. Darüber hinaus werden Implementierungen, die zu Maschinencode kompiliert werden, immer seltener. Compiler zielen zunehmend auf eine Art virtuelle Maschine.
Tatsächlich laufen die meisten Implementierungen auf der gleichen Grundstrategie zusammen. Der Compiler erzeugt Bytecode, der über eine JIT interpretiert oder zu nativem Code kompiliert wird. Es ist wirklich eine Mischung aus den traditionellen Ideen der Zusammenstellung und Interpretation.
Daher frage ich: Gibt es heutzutage einen nützlichen Unterschied zwischen interpretierten Implementierungen und kompilierten Implementierungen?
quelle
P-code
war 1966 erstmals eingeführt worden. IBM Aix gibt es seit 1986.Antworten:
Es ist wichtig, sich daran zu erinnern, dass Dolmetschen und Kompilieren nicht nur Alternativen zueinander sind. Am Ende wird jedes von Ihnen geschriebene Programm (einschließlich eines zu Maschinencode kompilierten) interpretiert. Das Interpretieren von Code bedeutet einfach, eine Reihe von Anweisungen zu übernehmen und eine Antwort zurückzugeben.
Kompilieren bedeutet andererseits, ein Programm in einer Sprache in eine andere Sprache zu konvertieren. Normalerweise wird angenommen, dass der Code bei der Kompilierung in eine "niedrigere" Sprache kompiliert wird (z. B. Maschinencode, eine Art VM-Bytecode usw.). Dieser kompilierte Code wird später noch interpretiert.
In Bezug auf Ihre Frage, ob es eine nützliche Unterscheidung zwischen interpretierten und kompilierten Sprachen gibt, ist meine persönliche Meinung, dass jeder ein grundlegendes Verständnis darüber haben sollte, was mit dem Code passiert, den er während der Interpretation schreibt. Wenn also ihr Code JIT-kompiliert oder Bytecode-zwischengespeichert wird usw., sollte der Programmierer zumindest ein grundlegendes Verständnis dessen haben, was dies bedeutet.
quelle
Die Unterscheidung ist von großer Bedeutung, da kompilierte Sprachen die Semantik in einer Weise einschränken, wie dies bei interpretierten Sprachen nicht unbedingt der Fall ist. Einige Interpretationstechniken sind sehr schwer (praktisch unmöglich) zu kompilieren.
Interpretierter Code kann beispielsweise zur Laufzeit Code generieren und diesen Code für lexikalische Bindungen eines vorhandenen Bereichs sichtbar machen. Das ist ein Beispiel. Zum anderen können Interpreter mit interpretiertem Code erweitert werden, der steuern kann, wie Code ausgewertet wird. Dies ist die Basis für alte Lisp-"fexprs": Funktionen, die mit nicht bewerteten Argumenten aufgerufen werden und entscheiden, was mit ihnen zu tun ist (uneingeschränkter Zugriff auf die erforderliche Umgebung, um den Code zu durchsuchen und Variablen auszuwerten usw.). In kompilierten Sprachen können Sie diese Technik nicht wirklich anwenden. Sie verwenden stattdessen Makros: Funktionen, die zur Kompilierungszeit mit nicht bewerteten Argumenten aufgerufen werden, und übersetzen den Code, anstatt ihn zu interpretieren.
Einige Sprachimplementierungen basieren auf diesen Techniken. Ihre Autoren lehnen das Kompilieren als wichtiges Ziel ab und begrüßen diese Art der Flexibilität.
Das Interpretieren ist immer nützlich, um einen Compiler zu booten. Ein konkretes Beispiel finden Sie in CLISP (eine beliebte Implementierung von Common Lisp). CLISP hat einen Compiler, der in sich selbst geschrieben ist. Wenn Sie CLISP erstellen, wird dieser Compiler während der ersten Erstellungsschritte interpretiert. Es wird verwendet, um sich selbst zu kompilieren. Sobald es kompiliert ist, erfolgt das Kompilieren mit dem kompilierten Compiler.
Ohne einen Interpreter-Kernel müssten Sie mit einem vorhandenen Lisp booten, wie es SBCL tut.
Mit der Interpretation können Sie eine Sprache von Grund auf neu entwickeln, beginnend mit der Assemblersprache. Entwickeln Sie die grundlegenden I / O- und Core-Routinen und schreiben Sie dann eine eval noch Maschinensprache. Sobald Sie eval haben, schreiben Sie in der Hochsprache; Der Maschinencode-Kernel führt die Auswertung durch. Verwenden Sie diese Funktion, um die Bibliothek um viele weitere Routinen zu erweitern und auch einen Compiler zu schreiben. Verwenden Sie den Compiler, um diese Routinen und den Compiler selbst zu kompilieren.
Interpretation: ein wichtiger Schritt auf dem Weg zur Zusammenstellung!
quelle
Tatsächlich werden viele Implementierungen von Sprachen immer noch streng interpretiert. Sie kennen sie möglicherweise nicht. Um nur einige zu nennen: die UNIX-Shellsprachen, die Windows-Cmd- und PowerScript-Shells, Perl, awk, sed, MATLAB, Mathematica usw.
quelle
Ich denke: Auf jeden Fall ja .
Tatsächlich zielt C ++ darauf ab, ein Konzept auf hoher Ebene, das normalerweise den Interpreten überlassen wird, auf die Compilerdomäne zu portieren, aber es bleibt auf der Minderheitenseite ...
quelle
Nützliche Unterscheidung: interpretierte Programme können sich ändern, indem sie zur Laufzeit Funktionen hinzufügen oder ändern.
quelle