Первый компилятор был написан Грейс Хоппер в 1952 году, в то время как интерпретатор Lisp был написан в 1958 году учеником Джона Маккарти Стивом Расселом. Написание компилятора кажется гораздо более сложной задачей, чем интерпретатор. Если это так, то почему первый компилятор был написан за шесть лет до первого интерпретатора?
history
compiler
interpreters
anguyen
источник
источник
Ответы:
Это может быть правдой сегодня, но я бы сказал, что это было не так 60 лет назад. Несколько причин почему:
источник
Фундаментальный момент заключается в том, что вычислительная аппаратная среда 1950-х годов сделала ее такой, что только компилятор был осуществим с учетом пакетной обработки компьютеров в то время.
В то время лучшие пользовательские интерфейсы были ограничены перфокартами и телетайпами . В 1961 году система SAGE стала первым дисплеем Cathode-Ray Tube (CRT) на компьютере. Таким образом, интерактивный характер переводчика не был предпочтительным или естественным намного позже.
Во многих компьютерах 1950-х годов для загрузки инструкций использовались переключатели на передней панели, а на выходе были просто ряды ламп / светодиодов, а любители даже использовали переключатели и светодиоды на передней панели в 1970-х годах. Может быть, вы знакомы с печально известным Altair 8800 .
Другие аппаратные ограничения также делали интерпретаторов невозможными. В 1950-х годах в компьютерах была крайне ограниченная доступность первичной памяти (например, ОЗУ). До появления полупроводниковой интегральной схемы (которая появилась только в 1958 году) память была ограничена памятью магнитного сердечника или памятью линии задержки, которая измерялась в битах или словах , без префикса. В сочетании с медлительностью памяти вторичного хранилища (например, диска или ленты), было бы сочтено расточительным, если не невозможно, использовать большую часть памяти, используемой для интерпретатора, даже до загрузки интерпретируемой программы.
Ограничение памяти по-прежнему было основным фактором, когда команда под руководством Джона Бакуса из IBM создала компилятор FORTRAN в 1954-57 годах. Этот инновационный компилятор был успешным только потому, что он был оптимизирующим компилятором .
Большинство компьютеров 1950-х годов практически не имели какой-либо операционной системы, не говоря уже о современных функциях, таких как динамическое связывание и управление виртуальной памятью, поэтому идея интерпретатора была слишком радикальной и непрактичной в то время.
добавление
Языки 1950-х годов были примитивными. Они включали лишь небольшое количество операций, на которые часто влияли либо инструкции базового оборудования, либо определение проблемы их целевого использования.
В то время компьютеры редко были компьютерами общего назначения в том смысле, в каком мы думаем о компьютерах сегодня. То, что они были перепрограммированы без необходимости перестраивания, считалось революционной концепцией - раньше люди использовали электромеханические машины (обычно калькуляторы) для вычисления или вычисления ответов (большинство приложений в 1950-х годах носили числовой характер).
С точки зрения информатики, компиляторы и интерпретаторы являются переводчиками и примерно одинаковы по сложности для реализации.
источник
Первые языки программирования были довольно простыми (например, без рекурсии) и были близки к машинной архитектуре, которая сама по себе была простой. Перевод был тогда простым процессом .
Компилятор был проще как программа, чем интерпретатор, который должен был бы хранить вместе данные для выполнения программы и таблицы для интерпретации исходного кода. И интерпретатору потребовалось бы больше места для себя, для исходного кода программы и для символьных таблиц.
Памяти может быть так мало (как по стоимости, так и по архитектурным причинам), что компиляторы могут быть автономными программами, которые перезаписывают операционную систему (я использовал одну из них). После компиляции ОС необходимо было перезагрузить, чтобы запустить скомпилированную программу. ... что дает понять, что работать переводчиком для реальной работы просто не вариант .
Чтобы быть правдой, простота, требуемая от компиляторов, была такова, что компиляторы были не очень хороши (оптимизация кода все еще находилась в зачаточном состоянии, когда вообще рассматривалась). Рукописный машинный код имел, по крайней мере, до конца шестидесятых годов, репутацию значительно более эффективного, чем код, сгенерированный компилятором. Была даже концепция коэффициента расширения кода , которая сравнивала размер скомпилированного кода с работой очень хорошего программиста. Обычно оно было больше 1 для большинства (всех?) Компиляторов, что означало более медленные программы и, что гораздо важнее, более крупные программы, требующие больше памяти. Это было все еще проблемой в шестидесятых.
Интерес компилятора заключался в простоте программирования, особенно для пользователей, которые не были специалистами по вычислительной технике, таких как ученые в различных областях. Этот интерес был не производительность кода. Но все же время программиста считалось дешевым ресурсом. Стоимость была в компьютерное время, до 1975-1980, когда стоимость перешла от аппаратного обеспечения к программному обеспечению. Это означает, что некоторые профессионалы не воспринимали всерьез даже компилятор .
Очень высокая стоимость компьютерного времени была еще одной причиной дисквалификации переводчиков , так что сама идея была бы смешной для большинства людей.
Случай с Лиспом очень особенный, потому что это был чрезвычайно простой язык, который сделал его выполнимым (а компьютер стал немного больше в 58). Что еще более важно, интерпретатор Lisp был доказательством концепции самоопределимости Lisp ( мета-цикличности ), независимо от какой-либо проблемы юзабилити.
Успех Lisp во многом связан с тем фактом, что эта самоопределимость сделала его отличным испытательным стендом для изучения структур программирования и разработки новых языков (а также для его удобства для символьных вычислений).
источник
Я не согласен с предпосылкой вопроса.
Первый компилятор адмирала Хоппера (A-0) был больше похож на компоновщик или язык макросов. Она хранит подпрограммы на ленте (каждая из которых имеет свой номер), и ее программы будут записаны в виде списка подпрограмм и аргументов. Компилятор скопирует запрошенные подпрограммы с ленты и переупорядочит их в полную программу.
Она использовала слово «компилировать» в том же смысле, в котором собрана антология стихов: собирать различные предметы в один том.
Насколько я могу судить, у этого первого компилятора не было лексера или парсера, что делает его отдаленным предком современного компилятора. Позже она создала еще один компилятор (B-0, он же FLOW-MATIC) с целью более похожего на английский синтаксиса, но он не был завершен до 1958 или 1959 года - примерно в то же время, что и интерпретатор Lisp.
Поэтому я думаю, что сам вопрос немного ошибочен. Похоже, что составители и интерпретаторы развивались почти одновременно, несомненно, из-за обмена идеями, которые заставили бы многих ученых думать в том же духе в те дни.
Лучший ответ с цитатами здесь: https://stackoverflow.com/a/7719098/122763 .
источник
Другая часть уравнения состоит в том, что компиляторы были ступенчатой абстракцией над ассемблером. Сначала у нас был жестко закодированный машинный код. «Мы» были ассемблером. Каждый прыжок, смещение и т. Д. Вычислялись вручную в гекс (или восьмеричное), а затем перфорировались в бумажную ленту или карточки. Поэтому, когда на сцену вышли ассемблеры, это сильно сэкономило время. Следующим шагом был сборщик макросов. Это дало возможность написать макрос, который расширится до набора машинных инструкций. Так что Фортран и Кобол были огромным шагом вперед. Нехватка ресурсов (хранилища, памяти и процессорных циклов) означала, что интерпретаторам общего назначения приходилось ждать развития технологий. Большинство ранних интерпретаторов были механизмами байт-кода (как сегодня Java или CLR, но с гораздо меньшими возможностями). UCSD Pascal был очень популярным (и быстрым) языком. MS Basic был байт-код движком под капотом.
С точки зрения накладных расходов, это полностью зависит от того, какой процессор запускается. В течение некоторого времени отрасль переживала большой кризис RISC против CISC. Я лично написал ассемблер для IBM, Data General, Motorola, Intel (когда они появились), TI и некоторых других. Существовала довольно значительная разница в наборах команд, регистрах и т. Д., Которые влияли бы на то, что требовалось для «интерпретации» p-кода.
Как пример времени, я начал программировать в телефонной компании около 1972 года.
источник
Если вы не держите все в памяти, скомпилированный код будет намного быстрее. Не забывайте, что в это время функции были присоединены к скомпилированному коду. Если вы не компилируете, вы не знаете, какие функции вам понадобятся. Итак, вы вызываете функции из ... О, еще не с диска, мы в начале 50-х, а с карт! Во время выполнения!
Конечно, можно найти обходные пути, но они еще не найдены, поскольку языки были очень просты и не так далеки от машинного кода. И компиляция была легкой и достаточно.
источник
До того, как был написан первый компилятор, люди писали ассемблерный код, который был огромным прогрессом по сравнению с простым двоичным кодом. В то время был веский аргумент, что код, скомпилированный компилятором, будет менее эффективным, чем код на ассемблере - в то время отношение (стоимость компьютера) к (стоимость программиста) сильно отличалось от сегодняшнего. Таким образом, было сильное сопротивление против компиляторов с этой точки зрения.
Но компиляторы намного эффективнее интерпретаторов. Если бы вы предложили написать переводчика в то время, люди бы подумали, что вы сошли с ума. Можете ли вы представить себе покупку компьютера за миллион долларов, а затем тратить 90% его мощности на интерпретацию кода?
источник
Прежде чем зациклить программу, она должна быть сохранена на носителе, который может быть прочитан повторно. В большинстве случаев единственным подходящим носителем будет ОЗУ. Поскольку код, как правило, вводится на перфокартах, которые - для читаемых человеком языков - скорее всего, будут в основном пустыми, необходимо выполнить некоторую обработку кода, прежде чем он будет сохранен в ОЗУ. Во многих случаях обработка текста перфокарты в форму, которая подходит для непосредственного выполнения процессором, на самом деле не сложнее, чем обработка его в форму, которая может быть эффективно обработана с помощью интерпретатора.
Обратите внимание, что целью ранних компиляторов было не создание файла на языке ассемблера или объектного кода на диске, а создание кода в ОЗУ, который был готов к выполнению. Это на самом деле на удивление легко, когда на пути нет операционной системы. Компилятор может генерировать код, начиная с одного конца памяти, и распределять переменные и цели перехода, начиная с другого. Если инструкция помечена меткой «1234», компилятор сохранит в переменной с именем «1234» инструкцию для перехода к текущему адресу генерации кода, создавая эту переменную, если она не существует. Оператор «goto 1234» создаст переменную «1234», если она не существует, и затем перейдет к этой переменной [которая, как мы надеемся, будет иметь переход в надлежащее местоположение, сохраненное в нем до выполнения этого оператора].
goto
метка, которая еще не была определена, так как она знает, когдаgoto
компилирует, куда она собирается перейти - к переменной. Возможно, это не самый эффективный способ генерации кода, но он соответствует размерам программ, которые компьютеры должны были обрабатывать.источник
Потому что для работы интерпретаторам нужны компиляторы.
Вышеприведенное утверждение не совсем верно. Строго говоря, вы можете создать интерпретатор, даже не используя и не взаимодействуя с компилятором. Но результаты этого не будут очень похожи на то, что вы подразумеваете под этими терминами.
В строгом смысле, компиляторы и интерпретаторы делают совершенно разные вещи. Компилятор считывает текст из некоторого источника и преобразует его в другой формат: ассемблер, машинный код, другой язык высокого уровня, структура данных или что-либо еще. Тем временем интерпретатор принимает какую-то структуру данных и на ее основе выполняет инструкции.
В настоящее время мы склонны считать «компилятором» компилятор, который был связан с генератором кода : программой, которая получает данные из некоторого источника и выводит код в некотором формате на основе того, что он видит. Это довольно интуитивно понятное использование для компиляторов, и это была одна из первых вещей, для которых были созданы компиляторы. Но если вы посмотрите на это по-другому, это похоже на то, что делает переводчик. Он всегда выводит код вместо выполнения более общих операций, но принцип тот же.
Если мы посмотрим на это с другой стороны, интерпретатор должен получить свои данные откуда-то . Это просто данные, поэтому вы можете создать их так же, как и любые другие данные. Поскольку речь идет об интерпретации, кажется естественным, что вы можете построить свои данные на основе инструкций в текстовом файле. Но для этого вам нужно что-то прочитать в тексте и создать структуру данных, и это компилятор . Он подключен к интерпретатору, а не к генератору кода, но все равно это компилятор.
Вот почему компиляторы были написаны первыми. Идея интерпретации структур данных не была новой, даже когда были задуманы компиляторы, но компиляторы были «недостающим звеном», которое позволяло программистам создавать эти структуры из текста.
источник
Еще один фактор: когда были написаны первые компиляторы, стоимость машинного времени была намного выше, чем сейчас. Переводчики используют намного больше машинного времени.
источник