Подтвердить что ты не робот

Что значит "Lisp может быть написано само по себе?"

Пол Грэхем писал, что "Необычная вещь о Lisp - на самом деле определяющее качество Lisp - заключается в том, что она может быть записана само по себе" . Но это не кажется для меня наименее необычным или окончательным.

ISTM, что язык программирования определяется двумя вещами: его компилятором или интерпретатором, который определяет синтаксис и семантику для языка по fiat и его стандартную библиотеку, которая в значительной степени определяет идиомы и методы, которыми обладают опытные пользователи будет использоваться при написании кода на языке.

С некоторыми конкретными исключениями (например, не члены С# семейства .NET) большинство стандартных библиотек языков написаны на этом языке по двум очень веским причинам: поскольку он будет использовать один и тот же набор синтаксических определения, соглашения о вызовах функций и общий "внешний вид" языка, а также потому, что люди, которые могут писать стандартную библиотеку для языка программирования, являются его пользователями и, в частности, его дизайнером. Так что там ничего особенного; это довольно стандартный.

И снова, нет ничего уникального или необычного в том, что компилятор языка написан сам по себе. Компиляторы C написаны в компиляторах C. Pascal, написанных на Паскале. Компилятор Mono С# написан на С#. Heck, даже некоторые языки сценариев имеют реализации, написанные сами по себе.

Итак, что означает, что Lisp необычен в том, что он написан сам по себе?

4b9b3361

Ответ 1

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

Ответ 2

Ну, ссылка, которую вы предоставили, продолжает говорить, что если вы продолжите читать, он подробно ответит на ваш вопрос.

Необычная вещь о Lisp - в факт, определяющее качество Lisp - заключается в том, что он может быть написан сам по себе. Чтобы понять, что подразумевал Маккарти это, мы собираемся восстановить его шаги, с его математическими обозначениями переведенный в обычный Common Lispкод.

Ответ 3

Я просто удалил очень длинный ответ, который, вероятно, здесь неуместен.

Однако учтите, что:

  • LISP не имеет "синтаксиса", если вы имеете в виду его со значением, которое оно имеет для такие языки, как C/Java/Pascal... есть (начальный, но настраиваемый) синтаксис для обычного читателя LISP, но это другое дело (LISP что Грэм говорит о не Common LISP, а читатель (the) не язык LISP, а просто процедура). Что-то вроде "(lambda (x) (* x 2))" - это не LISP код, но текст, который, например, стандартный читатель CL, может преобразовать в код LISP.

  • LISP не только может записываться в LISP (если вы имеете в виду способность "bootstrap" ) но он фактически появился таким образом. Самая первая реализация из eval в конце 1950 года был написан на бумаге, а затем преобразован вручную в машинный язык (1): LISP начался как чисто теоретическая идея, а не должен быть реализован. Я не знаю другого компьютерного языка этот путь. Например, С++ был задуман как предварительный процессор для компилятора C и был написан на C, это была не программа на С++, впоследствии преобразованная в C, чтобы быть способный запустить его.

Есть много других аспектов, в которых LISP совсем другой, и я думаю, что лучший способ понять его - фактически реализовать интерпретатор игрушек LISP (это задача меньше, чем можно было бы подумать особенно если ваш "машинный язык" - это высокоуровневый динамически типизированный язык, такой как Python).

(1) в http://www-formal.stanford.edu/jmc/history/lisp/node3.html вы можете найти, как Маккарти описывает, что eval[e, a] был найден на бумаге сначала как интересный теоретический результат (реализация "универсальной функции", чем универсальная машина Тьюринга), когда были созданы только структуры данных и элементарные нативные функции для языка LISP, который была создана группой. Эта рукописная функция была выполнена вручную С.Р. Рассел в машинный код и начал обслуживать их как первый интерпретатор LISP.

Ответ 4

Он не говорит, что Lisp можно использовать для написания компилятора Lisp. Он говорит, что язык составлен из собственных структур данных. Поэтому, пока вы не можете создать C-функцию из структур данных C, вы можете сделать это в Lisp. Программа состоит из списков, которые выполняются вашим компьютером, а эффект этих списков может заключаться в создании других списков, которые затем выполняются, а эффект от этих списков может заключаться в создании еще большего количества списков, которые должны быть выполнены. C не обладает этим свойством. C-код не может, например, манипулировать собственным AST.

Ответ 5

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

Это ядро ​​ Lisp.

Чтобы понять основные работы языка, нужно только посмотреть на одну страницу кода: он объясняет, как работают переменные, как работает вызов функции, как можно создавать новые функции и т.д.

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

Если вы посмотрите на реализацию PASCAL (в качестве примера), она не реализована в PASCAL, но в PASCAL + больше кода, который предоставляет необходимые структуры данных для представления языковых объектов, анализатора, компилятора, runtime,... - из коробки PASCAL не предлагает много - нужно построить их (или использовать библиотеку).

Вирт (создатель Паскаля) написал книгу, в которой объясняется реализация очень маленького языка, подобного Паскалю, - вам все равно придется писать значительный код для реализации этого языка - парсера, генератора кода, времени выполнения, загрузчика,...

Напротив, в Lisp исходный код Lisp имеет естественное представление, а основная процедура, которая оценивает код Lisp, - это всего лишь одна функция Lisp. Это может быть не реальная или практическая реализация Lisp, тем не менее она отличается от ситуации PASCAL, где исходный код не имеет полезного представления (кроме строки или файла), а механизм выполнения намного больше кода.

Итак, в Lisp имеем:

  • простое представление для исходного кода (списки символов)

  • простая реализация оценщика в одной небольшой функции

Кроме того, ничего не нужно для реализации оценщика Lisp в Lisp.