2013-09-01 5 views
3

Почему чистый Python не может быть полностью скомпилирован? Скомпилированный или интерпретированный является признаком реализации, а не языком. Итак, не должна ли быть какая-то реализация Python, которая полностью скомпилирована до собственного кода? Что делает (чистый) Python настолько сложным для компиляции?Почему чистый Python не может быть полностью скомпилирован?

Я знаю, что есть такие вещи, как PyPy и Cython, но как я понимаю тех, кто не являются чисто Python и требуют таких вещей, как аннотации типа и т.д.

благодаря

Полностью Составителю означая составлено до рук в родное кода, например, C или C++ или Lisp.

+0

Вам нужно было бы точно определить, что вы подразумеваете под «полностью скомпилированным». –

+1

Он * может * быть статически скомпилирован в машинный код, но для этого необходимо, чтобы виртуальная машина python была помещена в результирующий двоичный файл. –

+0

мой вопрос - почему. – Aristides

ответ

2

Я думаю, что самая большая проблема (и причина, по которой эти реализации требуют аннотации типов) заключается в том, что спецификация Python в значительной степени зависит от отсрочки семантической оценки, такой как привязка функции к времени выполнения.

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

Редактировать: Я отвечаю на подразумеваемый вторичный вопрос о том, почему кто-то не справился с этой проблемой, не соглашаясь с идеей, что это как-то невозможно. Сценарий C++, например, делает много отложенных привязок, но я считаю, что Python делает больше и делает это позже.

+0

«Вложение того, что составляет интерпретатор в результирующем исполняемом файле», - это то, что делают многие скомпилированные языковые реализации высокого уровня, например. Общий Лисп или Хаскелл. Они в большей степени называются системами времени выполнения. Исполняемый файл Haskell - это настоящая программа, встроенная в RTS, которая управляет памятью, профилированием, параллелизмом и тому подобным. Доведенный до крайности, РТС также мог интерпретироваться. – kqr

+1

Конечно, абсолютно. В какой-то момент подталкивание достаточного количества языка к оценке времени выполнения уменьшает разницу между «компиляцией» и «интерпретацией» до нуля. –

2

Ложное помещение. Python может быть полностью скомпилирован, никаких аннотаций типа или что-то в этом роде не требуется.

Кроме того, PyPy делает полностью компилирует код Python в машинный код. То, что это не сделано заблаговременно, не имеет отношения к аспекту компиляции - это всего лишь деталь реализации архитектуры JIT.

0

UPD: спасибо Konrad и kqr за то, что он указал только на этот вопрос только о компиляции стиля C или C++. Есть и другие способы сделать это, например, Common Lisp.

Строго говоря, вы не можете скомпилировать программу python заранее, потому что у вас не обязательно полный код во время компиляции. Программа python может загружать исходный код и передавать его через eval() для всего, что мы знаем. Или постройте его программно (в стандартной библиотеке он фактически делает именно это в namedtuple()).

Это не самая большая проблема, хотя - это маргинальные практики. Самая большая проблема заключается в том, что это невероятно сложно, возможно, вообще невозможно сделать вывод о типах данных заранее. Если у вас есть функция max(x, y), и вы хотите скомпилировать ее с помощью собственного кода, вам нужно знать, какие возможные типы для x и y, и скомпилировать другую версию для каждой комбинации. Это может быть проблемой. Теперь вы можете ограничить некоторые функции, чтобы сделать такое вывод возможным, и там вы получите RPython.

Таким образом, программа питона может быть собрана, но это трудно сделать заранее и целиком.

Вот почему есть PyPy! PyPy - это JIT compiler. Вместо того, чтобы вызывать, он запускает код и анализирует его во время его запуска. Вот почему он оптимизирует только петли.Вот как это работает (очень грубо):

  1. PyPy позволяет бежать петлю на время, не мешая, при сборе данных о его потоке (в настоящее время на 1000 итераций)
  2. На основе собранных типов данных и потока, оптимизированных ассемблерный код генерируется и компилируется.
  3. «Охранники» установлены, чтобы проверить, соответствует ли фактический поток программы прогнозируемому.
  4. Исходный код выполняется до тех пор, пока не загорится защитный огонь или концы петли.

Кроме того, при разработке PyPy разработчики создали RPython, который является подмножеством Python, который, по сути, может быть полностью и статически скомпилирован. Они достигли этого, главным образом, путем принудительного раннего связывания. Например, если у вас есть переменная, которая является целым числом, вы не можете переназначить ее как символ позже в строке. Кроме того, вы не можете смешивать разные типы данных в списках или других контейнерах и т. Д.

+1

Программа Common Lisp также может содержать вызовы 'eval' или' (max x y) ', и, тем не менее, невозможно их скомпилировать. – kqr

+0

Ваш аргумент не построен тщательно. Как сказал kqr, ничто не препятствует компиляции языков, содержащих 'eval'. Даже программы на C++ могут содержать моральный эквивалент функции eval. Для компиляции кода вам также не требуется полная информация о типе. В частности, Python использует динамический поиск в любом случае, и скомпилированные библиотеки C для Python делают то же самое во время выполнения. PyPy, конечно, идет еще дальше, но это не единственный способ выполнить компиляцию. –

+0

Конечно, вы всегда можете «скомпилировать» код, поместив виртуальную машину в исполняемый файл, как это делает lisp. Это не то, о чем я говорил. Я обращался к вопросу о переводе кода python на сборку аналогично C или C++. – letitbee

Смежные вопросы