Почему изучение lisp-интерпретатора в lisp так важно?

30

Я видел много учебных программ по CS и предложения для новых программистов, которые призывают начинающего программиста изучать интерпретатор lisp, который специально написан на lisp. Все эти сайты говорят что-то вроде «своего интеллектуального откровения», «это опыт просветления, который должен иметь каждый серьезный программист», или «он показывает вам аппаратные / программные отношения» и другие смутные утверждения, особенно из этой статьи, взятой из это уважаемое с практическими рекомендациями .

Общее мнение моего вопроса таково: как лисп достигает вышеуказанных целей и почему лисп? Почему не какой-то другой язык?

Я спрашиваю об этом, потому что я только что закончил писать интерпретатор схемы в схеме (взят из SICP http://mitpress.mit.edu/sicp/ ), и сейчас я пишу интерпретатор python в схеме, и я изо всех сил пытаюсь получить это легендарное прозрение это должно прийти конкретно от первого. Я ищу конкретные технические детали между двумя языками, которые я могу использовать в их интерпретаторах схем, чтобы понять, как работают программы.

Более конкретно:

Почему изучение переводчика, написанного на языке, который он интерпретирует, так подчеркнуто - это просто большое умственное упражнение, чтобы сохранить исходный язык и построенный язык прямо или есть конкретные проблемы, решения которых могут быть найдены только в природе оригинальный язык?

Как интерпретаторы LISP демонстрируют хорошие концепции архитектуры для будущего проектирования программного обеспечения?

Что бы мне не хватало, если бы я выполнил это упражнение на другом языке, таком как C ++ или Java?

Какой из этих упражнений чаще всего используется на вынос или «умственный инструмент»? **

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

Ма-на
источник
4
@gnat Не совсем советы по карьере, скорее вопрос «что такого хорошего в Лиспе».
Роберт Харви
1
@RobertHarvey, эта ссылка не только для карьеры, но и для образования совета, я имел в виду это. Но, Lisp-is-so-great тоже подходит, наверное,
коммент
1
Вы, кажется, спрашиваете, что вы узнаете из конкретного упражнения. Ваша скрытность - это признак лени, ключ к любому хорошему программисту, но независимо от того, что единственный способ узнать, чему вы научитесь из упражнения, - это сделать это и увидеть. Никто не может сказать вам, чему вы научитесь из этого, вам просто нужно будет это сделать.
Джимми Хоффа
2
Хотя этот вопрос относится к образованию в целом, я бы не стал его классифицировать как «совет по образованию» в смысле «Какой язык я должен изучать?» является. То есть это не характерно для определенного типа курса или работы. На самом деле, если вы отбросите некоторые образовательные модные слова, это вопрос о языках программирования в целом, ответы на которые обсуждают языковые особенности. Это на самом деле не специфично для Lisp, но может применяться к другим гомоиконическим языкам, таким как xslt. Поэтому я не буду говорить, что это идеальный вопрос, просто это не просто «совет по карьере».
TheRubberDuck

Ответы:

17

Если вы попробуете ответить «я тоже», вы увидите ...

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

Тогда вы могли бы понять, что за это удобство заплатили большую цену. В Лиспе программа тривиально создает другую программу и выполняет ее. В других языках это продвинутая техника, например, умножение на римские цифры.

Конечно, почти все будут спрашивать, "кому это нужно делать?" Ну, вы могли очень хорошо видеть, что это открывает целый ряд вещей, о которых вы даже не подозревали, что не могли сделать раньше. Вы можете сделать это на других языках, но не так просто.

ВСТАВЛЕН, чтобы ответить на комментарий Изката:

  • Программа понимания естественного языка SHRDLU работала, переводя английское утверждение или вопрос в программу на диалекте Lisp под названием MICRO-PLANNER и выполняя ее.
  • Программы, которые манипулируют программами, например, чтобы упростить их или доказать их правильность, естественно написаны на Лиспе.
  • Я использовал генерацию программы в программе для понимания визуальных сцен, где она должна была иметь дело со всеми симметриями, способными в трехмерных объектах, без умножения кода.
  • Все, что связано с логикой и доказательством теорем, имеет дело с манипулированием логическими выражениями, которые являются формой программы.
  • Символическая математика, такая как символьное интегральное или дифференциальное исчисление, включает манипулирование математическими выражениями, которые похожи на миниатюрные программы.
  • Любая проблема, связанная с генерацией кода или более высокоуровневым термином «частичная оценка», естественна в Лиспе. Я сделал это для программы моста базы данных очень давно. Я сделал это на C, который был не так прост, как Lisp, но я получил идею от Lisp. Это считалось техникой, которую почти никто не мог сделать в то время (особенно головы КОБОЛ). Может быть, больше сейчас, я надеюсь.

... это всего лишь несколько ...

Затем вы понимаете, что некоторые вещи, которые сегодня считаются «современными», были в Лиспе в течение 40 с лишним лет. Нравится функциональное программирование. Как сборка мусора. Как замыкания.

Это не значит, что у современных языков нет новых хороших идей, таких как ООП и т. Д. Но если вы изучите Lisp, это расширит ваши перспективы.

Майк Данлавей
источник
You can do it in other languages, but not nearly so easily.- Подобно? (Мне кажется, что вопрос в том, что подобные заявления часто делаются, но почти никогда не становятся более конкретными)
Izkata
Сначала я подумал, что мир революционизирован, когда понял, что javascript может печатать свой собственный исходный код, и объекты можно обойти, чтобы получить строковый литерал, который можно перевести в объектный литерал. Затем я понял, что Perl имел это все вместе с $ Data :: Dumper :: Deparse, и тогда я понял, что lisp имел это навсегда. Понимание интерпретаторов открывает эту мощь, которая всегда есть при создании живых модулей, а в Лиспе это более доступно, чем любой другой язык.
Дмитрий
забавно то, что программист на Лиспе, знающий о внутренностях Лиспа, всегда может создать свой собственный интерфейс Лисп для любого динамического языка от javascript до bash, perl или python; Лисп красиво загружается из доступной среды.
Дмитрий
19

Простой ответ на ваш вопрос - попробовать Lisp, желательно в сочетании с SICP . Тогда ты будешь просветленным.

Это сказал ...

Код - это данные. В
большинстве языков проводится четкое различие между кодом и данными; Лисп нет. Это позволяет, например, тривиально написать анализатор Lisp в Lisp и манипулировать кодом Lisp в Lisp. Лучшее описание этого просветления, которое я нашел, - «Природа Лиспа» .

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

Дальнейшее чтение,
бьющееся по средним

Роберт Харви
источник
3
2-й абзац не имеет смысла: гомойконичность! = Простой синтаксис; простой синтаксис позволяет легко написать анализатор Lisp на любом языке (см. это ). 3-й абзац расплывчат, нужен пример (ы).
@MattFenwick это правда, что гомойконичность может быть выполнена со сложным синтаксисом, но это будет чрезвычайно сложно. Справедливо предположить, что если вы имеете дело с гомо-звуковым синтаксисом, это будет просто, если только по какой-то другой причине, кроме требуемой последовательности, которая сделает его несказанно легче следовать, чем негомоиконический синтаксис. Хотя ваш второй пункт хорош, LISP легко разобрать, потому что это простой синтаксис, а не из-за гомоконичности (даже если гомоконичность является причиной такой простоты)
Джимми Хоффа
1
В любом случае, есть небольшая нагрузка на получение значения данных и интерпретацию его как программы. Это хорошая вещь. Программирование с помощью конфигурации является простым, когда все, что вам нужно сделать, это написать интерпретатор для данных конфигурации. Усовершенствованные математические преобразования (которые трудно реализовать в языках с сохранением состояния) часто «сводятся» к простым синтаксическим преобразованиям чистого фрагмента Lisp.
номен
1
@MattFenwick: Я удалил слово «гомоконичность» из своего ответа.
Роберт Харви
1
Я хотел бы дать больше, чем +1 за Природу Лиспа; Я никогда не видел такого замечательного объяснения.
Доваль
9

Почему изучение переводчика, написанного на языке, который он интерпретирует, так подчеркивается?

В целом, изучение переводчика дает вам понимание его языка и особенностей. В общем, изучение кода на языке программирования похоже на практику разговорного языка путем прослушивания и чтения: он знакомит вас с тем, что может делать этот язык, как он используется и общими «идиомами». Точнее говоря, Лисп - это гомоиконический язык, то есть его синтаксис для выражений такой же, как и его синтаксис для данных. Написание кода на Лиспе выглядит ужасно, как будто вы пишете список, и наоборот. Таким образом, интерпретировать код Lisp с помощью кода Lisp так же просто, как выполнять списки с помощью carи cdr.

Как мне извлечь выгоду из этого упражнения, чтобы получить максимальную отдачу от него в концептуальном плане?

Подумайте о том, как интерпретатор интерпретирует себя - во многих реализациях мета-циклического интерпретатора (где интерпретируется гомоиконический язык) можно просто «пройти» через функцию. Например, чтобы реализовать car, просто возьмите carаргумент. Это отвлекает внимание от механизмов хранения данных и фокусируется на функциональности.

Как интерпретаторы LISP демонстрируют хорошие концепции архитектуры для будущего проектирования программного обеспечения?

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

Что бы мне не хватало, если бы я выполнил это упражнение на другом языке, таком как C ++ или Java?

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

Какой из этих упражнений чаще всего используется на вынос или «умственный инструмент»?

Я не уверен, что у меня есть хороший ответ для этого; просто то, что это помогает увидеть, как работает интерпретатор, и, что еще важнее, повозится с ним, чтобы увидеть, как легко можно внести незначительные изменения в язык.

TheRubberDuck
источник
5

LISP сам по себе структурирован таким образом, что его чрезвычайно легко анализировать. Если вы попытаетесь написать компилятор, вы заметите, что намного проще, если все на вашем языке является выражением и имеет низкий уровень неоднозначности. LISP заставляет круглые скобки везде устранять двусмысленность и не имеет никаких утверждений, только выражения.

Сам факт, что LISP очень легко анализировать, побуждает пользователей анализировать свой собственный исходный код и делать с ним фокусы. Граница между данными и кодом становится размытой, и вы легко можете делать вещи, которые обычно требуют довольно больших усилий, такие как отражение, динамическое переписывание кода, плагины и сериализация.

Это суть этого. Это упражнение, вероятно, предназначено, чтобы дать вам некоторое представление о том, что возможно, когда код легко разбирается из самого себя.

Александр Торстлинг
источник
Это не Лисп, который легко разобрать. S-выражения легко разбирать. Кроме того, вам ТОГДА нужно разобрать Лисп.
Райнер Йосвиг
@Rainer: Разве это не просто придирки? В моем мире синтаксический анализ означает переход от текста к AST, который ничего не говорит о интерпретации команд.
Александр Торстлинг
В C ++ парсер обнаружит синтаксически неправильное объявление функции. В Лиспе нет. Читатель ничего не знает о языке программирования Lisp. Синтаксический анализатор C ++ знает полный синтаксис C ++. Читатель Lisp знает только s-выражения.
Райнер Йосвиг
Ах, тогда я понимаю, что вы имеете в виду. Правда, хотя я все еще думаю, что простой оценщик lisp будет проще построить, чем простой c ++. Это то, что они делают в SICP, не так ли (с тех пор, как я это прочитал)?
Александр Торстлинг
язык, используемый в SICP, очень прост, даже не полная схема. Интерпретатор для крошечного C-подобного языка также должен быть простым. C ++ большой. Некоторая трудность связана с относительно большим количеством встроенных синтаксисов. В типичной системе Lisp большая часть синтаксиса строится с помощью макросов - вне интерпретатора. Макросы реализуют синтаксис и механизм расширения для исходных преобразований. Это держит ядро ​​меньше. Но макросы могут быть массивными. Например, реализация для конструкции LOOP содержит более 2000 строк сложного макрокода.
Райнер Йосвиг
4

Я не уверен, что это действительно важно для всех. Вы можете быть успешным разработчиком, не зная, как работает интерпретатор Lisp. При изучении информатики, основные идеи Lisp должны быть изучены, хотя.

Интерпретаторы Lisp важны для программистов на Lisp. Им нужно понять, как работает Интерпретатор ([и компилятор] 1 ), чтобы полностью понять, как использовать язык.

Интерпретатор Lisp часто используется как инструмент в информатике, чтобы научить студентов нескольким вещам:

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

Райнер Йосвиг
источник