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

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

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

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

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

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

21
задан casperOne 29 April 2012 в 15:20
поделиться

5 ответов

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

11
ответ дан 29 November 2019 в 21:05
поделиться

Что ж, в предоставленной вами ссылке говорится, что, если вы продолжите читать, он подробно ответит на ваш вопрос.

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

6
ответ дан 29 November 2019 в 21:05
поделиться

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

Это ядро ​​Lisp .

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

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

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

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

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

Итак, в Лиспе мы имеем:

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

  • простую реализацию вычислителя в одной маленькой функции

Кроме этого, для реализации Лиспа ничего не требуется оценщик в Лиспе.

4
ответ дан 29 November 2019 в 21:05
поделиться

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

6
ответ дан 29 November 2019 в 21:05
поделиться

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

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

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

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

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

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

7
ответ дан 29 November 2019 в 21:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: