Интерпретировано против скомпилированных и поздних привязок
Python скомпилирован в промежуточный байт-код (pyc), а затем выполняется. Итак, есть компиляция с последующей интерпретацией. Однако давние пользователи Python говорят, что Python является "позднесвязывающим" языком и что он не должен упоминаться как интерпретируемый язык.
-
Как Python будет отличаться от другого интерпретируемого языка?
-
Не могли бы вы рассказать мне, что означает "поздняя привязка", в контексте Python?
Java - это еще один язык, который сначала имеет исходный код, скомпилированный в байт-код, а затем интерпретируемый в байт-код.
-
Является ли Java интерпретированным/скомпилированным языком?
-
Как это отличается от Python с точки зрения компиляции/выполнения?
-
Говорят, что Java не имеет "позднего связывания". Связано ли это с тем, что Java-программы работают быстрее, чем Python?
Было бы здорово, если бы вы могли также дать мне ссылки на места, где люди уже обсуждали это; я бы хотел больше узнать об этом. Спасибо.
Ответы
Ответ 1
Позднее связывание - это совсем другое понятие для интерпретации.
Строго говоря, интерпретируемый язык выполняется непосредственно из источника. Он не проходит этап составления байтового кода. Путаница возникает из-за того, что программа python является интерпретатором, но интерпретирует байт-код, поэтому это байт-код Python, который вы бы назвали "интерпретированным". Сам язык Python является скомпилированным языком.
Java байт-код, напротив, интерпретируется и компилируется в наши дни. Он скомпилирован в собственный код JIT-компилятором и затем запускается непосредственно на аппаратном обеспечении.
Late binding является свойством системы типов и присутствует в большинстве языков в некоторой степени независимо от того, интерпретируются ли они или компилируются.
Ответ 2
Как Python будет отличаться от другого интерпретируемого языка?
Это связано с расщеплением волос. Интерпретированные языки и языки с управляемым кодом, такие как языки С# и виртуальной машины (например, Java), образуют странный континуум. Есть люди, которые скажут, что все языки "интерпретируются" - даже машинный язык. В конце концов, электронные схемы процессора "интерпретируют" машинный язык.
Лучшее, что вы можете сделать, это сказать, что "интерпретируемый" означает наличие видимого уровня программного обеспечения, интерпретирующего ваши байтовые байты приложения. "не интерпретируемый" означает, что ваше программное обеспечение (более или менее) напрямую выполняется базовым оборудованием. "Управляемый код" люди могут продолжать разделять эти волосы.
Не могли бы вы рассказать мне, что означает "поздняя привязка", в контексте Python?
Переменные не объявлены как имеющие тип. Переменная привязана к типу как можно ближе - с назначением фактического объекта.
Является ли Java интерпретированным/скомпилированным языком?
Да. Он скомпилирован в байтовые коды. Байт-коды интерпретируются. Я предпочитаю называть это интерпретируемым.
Однако люди будут (по-настоящему неясным причинам) не согласиться. Наличие какого-либо "компиляционного" шага - пусть и минимального - всегда путает людей. Перевод в байтовый код практически не влияет на фактическое поведение программы во время выполнения. Некоторым людям нравится говорить, что только языки, которые полностью свободны от любой компиляции предварительной обработки, могут быть интерпретированы. Их уже не так много, так как многие языки переведены из текста, удобного для людей, в интерпретатор дружественных байтовых кодов. Даже Applesoft Basic (еще в 80-х годах) прошел этот перевод, когда вы ввели код.
Некоторые JVM делают JIT. Некоторые этого не делают. Некоторые из них представляют собой смесь. Сказать, что JVM делает только неправильный перевод кода байта JIT. Некоторые JVM делают. Некоторые не делают.
Как это отличается от Python с точки зрения компиляции/выполнения?
Совсем нет. Java VM может выполнять Python. [Для легко путаемого слово "python" в этом контексте не может означать "источник python". Это должно означать байт-код python.]
Говорят, что Java не имеет "позднего связывания". Связано ли это с тем, что Java-программы работают быстрее, чем Python?
Может быть. Java-программы часто бывают быстрее из-за компиляторов JIT, которые переводят байт-код Java в машинный код во время выполнения.
Статическая ( "ранняя" ) привязка не имеет такого же преимущества для Java, что и у нее с действительно скомпилированным языком, например C или С++, где почти нет проверок времени выполнения. Java по-прежнему делает такие вещи, как проверка границ массива, что C omits в интересах необработанной скорости.
На самом деле для "позднего" привязки фактически мало штрафа. Атрибуты и методы Python разрешаются с помощью простого поиска в словарях. Словарь - хэш; производительность неплохая. Хэши для имен могут быть помещены в "интернированный" строковый литерал, амортизирующий стоимость вычисления хэша.
Для настоящей забавы посмотрите PyPy и RPython. Это интерпретатор Python, который может компилировать JIT. Вы завершаете двухуровневый переводчик. Ваш код интерпретируется PyPy. PyPy интерпретируется RPython. http://alexgaynor.net/2010/may/15/pypy-future-python/
Ответ 3
Существует связь между тем, что мы называем временем связывания и понятием интерпретации/компиляции.
Время привязки - это время, когда символическое выражение привязано к его конкретному значению. Это больше связано с определением языка программирования, например. динамическое и статическое определение переменных. Или статический метод против виртуальных методов или динамическая типизация или статическая типизация.
Затем идет реализация языка. Чем больше информации статически известно заранее, тем легче писать компилятор. И наоборот, чем позднее ограничение языка, тем труднее оно. Следовательно, иногда приходится полагаться на методы интерпретации.
Однако различие между ними не является строгим. Мы не только можем считать, что все в конечном итоге интерпретируется (см. Ответ S.Lott), но часть кода может быть скомпилирована, декомпилирована или перекомпилена динамически (например, JIT), что делает различие очень нечетким.
Например, динамическая загрузка классов в Java идет в категории "поздняя привязка": набор классов не фиксируется один раз для всех, а классы могут загружаться динамически. Некоторые оптимизации могут быть выполнены, когда мы знаем набор классов, но должны быть признаны недействительными после загрузки новых классов. То же самое происходит с возможностью обновления метода с помощью инфраструктуры отладки: JVM необходимо будет де-оптимизировать все сайты вызовов, если бы метод был встроен.
Я мало знаю о Python, но практикующие Python предпочитают, возможно, термин "поздняя граница", чтобы избежать такой путаницы.
Ответ 4
Я думаю, что распространенное заблуждение, которое интерпретируется Python при компиляции Java, возникает из-за того, что Java имеет явный шаг компиляции - вам нужно запустить javac, чтобы преобразовать ваш .java исходный файл в файл .class bytecode, который можно запустить.
Как вы справедливо указываете, что Python аналогично компилирует исходные файлы в байт-код, но он делает это прозрачно - компиляция и запуск обычно выполняются за один шаг, поэтому это менее очевидно для пользователя.
Важное различие между ранним и поздним связыванием и динамическим и статическим типированием. Скомпилированное/интерпретируемое различие бессмысленно и не имеет значения.
Ответ 5
время привязки - это когда имена решаются на вещи.
Более динамичные языки имеют тенденцию к позднему связыванию.
Это может быть отдельно от интерпретации/компиляции - например,
Методы objective-C разрешаются с опозданием и динамически сравниваются с С++.
Java делает большую часть привязки при загрузке класса: позже C, но
раньше, чем Python.
моя любимая цитата из Stan Kelly-Bootle Computer Contradictionary:
время привязки n. Момент, когда хеш-таблица становится поврежденной.
== > Достижения в области вычислений могут быть сопоставлены с "опозданием привязки", что заставляет меня думать о моей так называемой так называемой карьере CS: золотом прошлом, сером настоящем и розовом будущем. Это моя версия оптимизма Synge: трава зеленая, за исключением t = 0. В EDSAC я мои функции (5ch-подпрограммы с бумажной лентой) были пробиты, сращены и привязаны примерно за две недели до ввода. Это известно как обязательное связывание и требует ловкости с помощью эластичных полос. Затем Фортран пришел с новым видом привязки: грязными колодами карт, которые не перетасовывались. Затем с Algol и C мне понравилось статическое (компиляция) привязка, пока С++ не принесла ошеломляющие радости динамического (run-time) привязки. Мои текущие исследования направлены на то, чтобы отложить привязку до тех пор, пока она не будет выполнена. Я называю это связующим звеном в конце, как было предсказано в Евангелии от Матфея: "... и все, что ты свяжешь на земле, должно быть связано на небе..." (Матфея 16:19 KJV).