Интерпретируемый язык программирования


Интерпретируемый язык программирования — язык программирования, исходный код на котором выполняется методом интерпретации[1]. Классифицируя языки программирования по способу исполнения[2], к группе интерпретируемых относят языки, в которых операторы программы друг за другом отдельно транслируются и сразу выполняются (интерпретируются)[3] с помощью специальной программы-интерпретатора (что противопоставляется[1] компилируемым языкам, в которых все операторы программы заранее оттранслированы в объектный код[3]). Такой язык может реализовывать конструкции, допускающие динамические изменения на этапе выполнения (модификация существовавших или создание новых подпрограмм). Эти конструкции затрудняют компиляцию и трансляцию на компилируемый язык[1].

В общем случае, любой язык может быть компилируемым и интерпретируемым. В предельном случае такой язык можно реализовать только при помощи интерпретаторов[4]. Также встречаются названия interpretative language («интерпретативный»)[4], interpretable language («поддающийся интерпретации»), interpreted language («интерпретируемый»)[5].

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

Большое количество языков, включая Бейсик, Си, Лисп, Паскаль и Python, имеют обе реализации. В Java используется JIT-компиляция для генерации машинного кода, хотя изначально он переводится в интерпретируемую форму. Языки Microsoft .NET Framework компилируются в Common Intermediate Language (CIL), который во время выполнения компилируется в машинный код. Большинство реализаций Лиспа позволяют смешивать оба вида кода.

В ранние годы развития программирования на языки сильно влиял выбор способа выполнения. Например, компилируемые языки требовали задания типа данных переменной в момент её описания или первого использования. В то время как интерпретируемые языки в силу своей динамической природы позволяли отказаться от этого требования, что давало больше гибкости и ускоряло разработку.

Изначально интерпретируемые языки преобразовывались в машинный код построчно, то есть каждая логическая строка компилировалась непосредственно перед выполнением. В результате каждая инструкция, заключенная в тело цикла и исполняемая несколько раз, столько же раз обрабатывалась транслятором. В настоящее время такие эффекты редки. Большинство интерпретируемых языков предварительно транслируются в промежуточное представление. Оно представляет собой байт-код или шитый код (threaded code). Это набор инструкций по вызову небольших фрагментов более низкоуровневого кода, эквивалентный нескольким командам ассемблера или командам виртуальной машины соответственно. Уже этот код исполняется интерпретатором или виртуальной машиной. Например, такую схему используют Java, Python и Ruby (использует представление кода в виде абстрактного синтаксического дерева).