Почему существует такой четкий разрыв между интерпретируемыми и скомпилированными языками?

При изучении скомпилированного языка, такого как C или C++, вы знакомитесь с компилятором. Чтобы запустить ваш код, вы должны сначала скомпилировать его. Компиляция вашего кода переводит его из текстового представления во что-то, что может быть выполнено. Результирующий код очень быстрый и может использовать препроцессоры и тому подобное.

При изучении динамического языка, такого как Python, Matlab или Ruby, вы знакомитесь с переводчиком. Чтобы запустить ваш код, просто введите его в интерпретатор. Таким образом, вы можете играть со своим кодом во время выполнения и изменять поведение вашей программы на лету. Недостатком этого является то, что интерпретируемые языки довольно медленные, а отсутствие четкого времени компиляции делает невозможным препроцессоры.

Кроме того, существуют компиляторы "точно в срок", которые используются как интерпретируемые языки, но с меньшим дефицитом производительности по сравнению со скомпилированными языками. Но они обычно не используют препроцессоры и не выводят готовые к работе двоичные файлы.

А потом я изучил Lisp, который можно компилировать, интерпретировать и что у вас есть, при этом будучи быстрым и обладающим мощной системой предварительной обработки (макросами). Это кажется здравым смыслом в мире Lisp, но не где-либо еще.

Почему нет популярных интерпретаторов для C или компиляторов для Python? Почему сильный разрыв между интерпретируемыми и компилируемыми языками? (Я знаю, что существуют проекты, которые могут компилировать Python или интерпретировать C, но в целом они, похоже, не очень популярны).

1 ответ

Решение

Большинство популярных скомпилированных языков были разработаны с нуля для компиляции: они, как правило, избегают функций, которые затрудняют создание эффективного скомпилированного кода. Эти языковые функции включают удобные "динамические", такие как динамическая типизация, неоднородные контейнеры и специальные пространства имен объектов.

Таким образом, интерпретатор для скомпилированного языка не может использовать преимущества динамических функций, доступных для интерпретируемого языка, но не имеет преимуществ в производительности скомпилированной реализации.

И наоборот, компилятор должен дублировать все функции и поведение интерпретируемого языка, независимо от затрат. В общем, это означает, что скомпилированная программа для интерпретируемого языка будет нести большую часть работы интерпретатора. В качестве одного примера, любой вид eval() Функциональность эффективно требует включения переводчика.

Наконец, эти эффекты усиливаются взаимно усиливающими преимуществами большой пользовательской базы, хорошей поддержкой и надежной реализацией.

Другие вопросы по тегам