Действительно тонкий вопрос ... Раньше «интерпретируемые» языки анализировались и преобразовывались в промежуточную форму, которая выполнялась быстрее, но «машина», выполнявшая их, была довольно специфичной для языка программой. Вместо этого «скомпилированные» языки переводились в инструкции машинного кода, поддерживаемые компьютером, на котором они выполнялись. Раннее различие было очень простым - статический и динамический прицел. В статически типизированном языке ссылка на переменную может быть в значительной степени разрешена в адрес памяти с помощью нескольких машинных инструкций - вы точно знаете, где в вызывающем кадре ссылается переменная. В языках с динамической типизацией вам приходилось искать (вверх по списку A или вверх по фрейму вызова) ссылку. С появлением объектно-ориентированного программирования непосредственный характер ссылки расширился до многих других концепций - классов (типов), методов (функций), даже синтаксической интерпретации (встроенные DSL, такие как регулярное выражение).
Фактически, различие, восходящее, возможно, к концу 70-х годов, заключалось не столько между скомпилированными и интерпретируемыми языками, сколько в том, выполнялись ли они в скомпилированной или интерпретируемой среде. Например, Паскаль (первый язык высокого уровня, который я изучил) работал в Калифорнийском университете в Беркли сначала на интерпретаторе Билла Джоя pxp, а затем на компиляторе, который он написал pcc. Один и тот же язык, доступный как в скомпилированной, так и в интерпретируемой среде.
Некоторые языки более динамичны, чем другие, значение чего-либо - типа, метода, переменной - зависит от среды выполнения. Это означает, что скомпилировано или нет, есть существенный механизм времени выполнения, связанный с выполнением программы. Forth, Smalltalk, NeWs, Lisp - все были примерами этого. Первоначально для этих языков требовалось столько механизмов для выполнения (по сравнению с C или Fortran), что они были естественными для интерпретации.
Еще до Java были попытки ускорить выполнение сложных динамических языков с помощью приемов, таких как поточная компиляция, своевременная компиляция и т. Д.
Я думаю, что это была Java, которая была первым широко распространенным языком, который действительно запутал пробел между компилятором и интерпретатором, по иронии судьбы не для того, чтобы он работал быстрее (хотя и это тоже), а для того, чтобы он работал везде. Определяя свой собственный машинный язык и «машинный» байт-код java и виртуальную машину, Java попыталась стать языком, скомпилированным во что-то близкое к любой базовой машине, но не к реальной машине.
Современные языки сочетают в себе все эти инновации. Некоторые из них обладают динамической, открытой, «вы не знаете-что-получите-до-выполнения» природой традиционных «интерпретируемых языков» (ruby, lisp, smalltalk, python, perl (!)), Некоторые пытаются имеют строгость спецификации, позволяющую обнаруживать статические ошибки на основе типов в традиционных компилируемых языках (java, scala). Все они компилируются в фактические машинно-независимые представления (JVM) для получения семантики однократного выполнения записи в любом месте.
Итак, скомпилировано или интерпретировано? Я бы сказал, лучшее из обоих. Весь код находится в исходном коде (с документацией), можно что-либо изменить, и эффект сразу же, простые операции выполняются почти так же быстро, как и оборудование, сложные поддерживаются и достаточно быстры, модели оборудования и памяти согласованы на разных платформах.
Сегодня большая полемика в языках, вероятно, связана с тем, имеют ли они статическую или динамическую типизацию, то есть не с какой скоростью они будут работать, а с тем, будут ли ошибки обнаруживаться компилятором заранее (за счет того, что программисту придется указывать довольно сложную типизацию). информации) или будут ли ошибки возникать при тестировании и производстве.
person
marc meyer
schedule
02.06.2011