Является ли ИНТЕРПРЕТР анти-шаблон?

Для меня интерпретатор Interpreter очень похож на анти-шаблон, известный как десятое правило Greenspun:

Любая достаточно сложная программа C или Fortran содержит специальную, неформальную, ограниченную ошибками, медленную реализацию половины Common Lisp.

То есть, если вам нужно использовать Interpreter, вы, вероятно, создадите что-то медленное, ad hoc и плохо указанное. Правильное решение - использовать правильный язык с самого начала.

Или, в качестве альтернативы, вставьте хорошо известный и хорошо определенный язык в ваше приложение, например Guile (встраиваемая схема GNU). Или используйте Haskell в качестве встроенного языка, специфичного для домена.

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

(Я не особенно поклонник lisp. Это хорошо, но так C и Haskell и python и многие другие языки.)

Ответ 1

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

Знание того, когда использовать шаблон, не позволяет ему быть анти-шаблоном.

Ответ 2

Любой шаблон дизайна представляет собой анти-шаблон, если его неправильно использовать.

Хорошее использование шаблон интерпретатора:

  • Программный компилятор
  • Модуль оценки SQL
  • Анализатор ввода графического калькулятора
  • XML-парсер

Это все программы, которые решают проблему оценки слов на языке, независимо от того, какой язык может быть.

Ответ 3

Имейте в виду, что "шаблон интерпретатора" представляет собой особый шаблон проектирования в ООП.

Это не имеет ничего общего с "интерпретаторами" или их использованием в целом.

Ответ 4

В какой-то момент проекту, вероятно, понадобится система конфигурации. что-то простое, как правило, все, что нужно сначала, что-то вроде пар ключ-значение, чтобы система могла подключаться к локальной базе данных или к некоторым из них. Если это все, что нужно, его общее просто взломать простой парсер для диалекта INI или CSV и двигаться дальше. Но по мере роста и созревания системы большее значение придается конфигурации. Это нормальная и здоровая функция рефакторинга и ответственность за правильный уровень абстракции. Отсюда разработчикам или даже пользователям (вздохам) будет недолго желать более выразительного языка конфигурации. Прежде чем кто-нибудь даже заметит, система имеет полный язык обучения, встроенный и используемый.

Это основная схема Greenspunning. Все было хорошо спроектировано до последнего бит, где специальный язык был ввергнут в реальную вычислительную работу.

Любая система достойного размера, вероятно, должна содержать как минимум половину клифра.

Зная, что заранее это большой шаг. Очень удобный способ писать большие системы - это выбрать хороший, легко взломанный язык интерпретации и написать в нем свою систему. Это происходит именно так, как это делает TCL, но в наши дни трудно заставить кого-то за крупным проектом на этом языке. С другой стороны, есть много других языков, которые теперь предлагают все эти преимущества.

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

Примером этого в дикой природе является django settings.py. По какой-то причине django не очень умен, чтобы угадать, где установлен проект django. Используя в файле конфигурации стандартный питон, это можно переносить в общем случае портативным способом, который подходит почти каждому пользователю. Несмотря на это, большая часть файла settings.py выглядит как простые старые пары key = value, типичные для конфигурационных файлов стиля .ini.

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

Ответ 5

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

Шаблон интерпретатора больше связан с идеей сохранения графа объектов, но выбирает формат персистентности, который является читаемым человеком и редактируемым человеком (например, 2 + 3, представляющий объект Addition с указателями на пару Integer объектов). Даже если это никогда не подвергается клиентам как "язык", оно по-прежнему помогает отладке, поддержке, хакерству и т.д. Другими распространенными примерами были бы языки запросов, такие как HQL в [N] Hibernate - никакой существующий язык не был бы столь же хорош для описания запроса на этом уровне абстракции.

Как было предложено другими, XML обычно используется в качестве базового синтаксиса для этого (особенно при понимании графа сохраняемых объектов как "файла конфигурации" и см. также Microsoft XAML), но это фактически неоптимальный выбор. JSON в UTF-8 (или аналогичный) будет чище, проще разбираться, читаться и редактироваться, и, вероятно, лучше для большинства приложений. Но есть несколько больших библиотек парсера, которые используют описание синтаксиса типа BNF, а затем могут анализировать текст в DOM-подобную переходную структуру во время выполнения, поэтому проблема с синтаксисом с высокой четкостью не является проблемой.

Ответ 6

Возможно, реализация компилятора Lisp включает пример шаблона интерпретатора.

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

Ответ 7

Интерпретатор - это идея генератора парсеров JavaCC. Я думаю, что все нормально.

Интерпретатор является гораздо более респектабельным шаблоном GoF, чем Singleton. Это тот, который нужно проголосовать за остров. Возможно, Memento также.

Ответ 8

Одна из причин, по которой был изобретен XML, заключалась в том, чтобы спасти нас от всех письменных переводчиков EDI; но, по крайней мере, область была четко определена, и все мы сделали ее примерно одинаково (по крайней мере достаточно) эффективно. По крайней мере, я все еще достаточно обманута, чтобы думать, что это правильно.

Похоже, вы пытаетесь начать новую городскую легенду? Вы врожденно возражаете против доменных языков?

Ответ 9

Вы, очевидно, не поклонник Lisp ", потому что мальчики и девочки, которые подходят к этому описанию, обычно могут полагаться на то, что Lisp является скомпилированным языком. Lisp появился в 1958 году. В руководстве 1961 года Lisp 1 уже описывается компиляция.

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

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

Реализация CLISP ANSI Common Lisp является хорошим примером этого. Для создания CLISP вам нужен только компилятор C. CLISP Lisp компилятор написан в Lisp. Поэтому, конечно, вам нечего запускать с этим компилятором. Решение заключается в интерпретации компилятора с использованием интерпретатора, написанного на C.

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

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

Без интерпретатора компилятор CLISP может быть только загружен, настаивая на том, что сначала будет установлена ​​реализация Lisp. (Как вам нужен компилятор C для повышения GCC). Или иначе, CLISP-компилятор должен быть написан на C, чтобы компилятор был скомпилирован с использованием существующего компилятора C, а затем применен к Lisp коду для его компиляции до его запуска.

Никто в здравом уме не хочет писать компилятор Lisp в C, а выполнение Lisp для реализации реализации Lisp - большой недостаток в мире, в котором Lisp не является вездесущим. То, что произойдет с моделью обтекания Lisp -compiler-in-C, заключается в том, что компилятор Lisp, написанный на C, будет полностью минимальным и, возможно, неполным, который испускает код низкого качества, только достаточно хороший, чтобы инициировать повышение уровня и "реальный" компилятор все равно будет записан в Lisp.

Ответ 10

Как правило, фазы компилятора/интерпретатора выглядят следующим образом:

  • Синтаксис
  • Дерево обработки
  • AST
  • Скомпилировать или интерпретировать

В Lisp, 1 и 2 объединены в 3.

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

Однако я должен был бы сказать, что ручная работа с деревьями АСТ неприятна и не является конечным для любого языка, независимо от того, сколько из них утверждает Lispers.