Конечно, вы можете реализовать то, о чем говорите, на Лиспе.
Одно большое различие между Лиспом и другими языками заключается в том, что ничто не фиксировано, и вы контролируете, что делает читатель с каждым символом входного исходного кода. Буквально.
Рассмотрим, например, проект CL-Python и его смешанный синтаксис в режиме Lisp/Python. а>.
По сути, в этом режиме, если то, что вы вводите, начинается с открытой скобки, то это считается Lisp, в противном случае это считается Python (включая многострочные конструкции).
...ОДНАКО...
этот тип библиотеки макросов/читающих макросов реализуется редко, потому что одним из основных преимуществ подхода s-expression является то, что он хорошо компонуется, и вы можете создавать другие макросы поверх существующих макросов, повышая уровень языка.
После отказа от регулярности подхода s-выражений написание макросов становится раздражающим, потому что для написания кода, который манипулирует кодом, вам необходимо учитывать несколько различных конструкций языка, правила приоритета, специальные правила, специальные формы синтаксиса.
Языки, которые не основаны на s-выражении, иногда обеспечивают реальную возможность обработки макросов, но работают на уровне AST, то есть после того, как некоторая обработка синтаксического анализа уже выполнена фиксированным образом. Более того, код макроса на этих языках выглядит очень странно, потому что код, которым макрос манипулирует, проверяет или создает, не похож на настоящий код.
Иногда в других языках вместо этого вы найдете только текстовые макросы, которые в основном являются поиском и заменой. Чтобы увидеть пример того, насколько уродливыми могут быть вещи, рассмотрим стандартную библиотеку Python реализация collections.namedtuple (около строки 284) и набор абсурдных ограничений, вызванных только этой реализацией.
Другим примером того, как все может стать ужасно сложным, если вы заставите себя использовать только шаблонный подход, чтобы избежать сложности манипулирования нерегулярным языком с особым регистром, является метапрограммирование шаблонов C++.
Вместо этого простой язык, основанный на s-выражениях и квазицитировании, делает код макросов намного проще для написания, чтения и понимания, и поэтому код Лиспа не отходит от него. Не потому, что нельзя, а потому, что нет смысла переходить к худшему синтаксису без причины.
В Лиспе вы немного «изгибаете» язык, добавляя абстракции, которые действительно необходимы, не нарушая при этом всего остального и, что наиболее важно, не отказываясь от возможности делать больше изгибов в будущем, если это необходимо. Написание макроса/макроса чтения, который превращает синтаксический анализ выражения в кошмар, скажем, C++, и в то же время лишает возможности писать дополнительные макросы и добавлять больше конструкций (или делает это невероятно сложным), было бы бессмысленным самоубийством.
Даже такой макрос, как (infix x + y * z)
, это всего лишь упражнение... Сомневаюсь, что какой-нибудь шепелявый будет использовать его для написания настоящего кода... с какой стати кому-то снова вводить абсурдную двойственность функции/оператора и кошмар правил приоритета/ассоциативности? Если вам не нравится Лисп, просто не используйте Лисп.
Для шепелявого уродливы не части (infix
и )
... а то, что посередине.
Также почему вы думаете, что 2+3*6 "естественно" равно 20? Потому что учитель бил вас палкой по ладоням, когда вы были ребенком, пока вы не поняли правильно?
person
6502
schedule
14.07.2015
eval-when
верхнего уровня, которая включает:compile-toplevel
и/или:load-toplevel
, тело которой изменяет текущий*readtable*
на тот, который может читать инфиксную нотацию. Вам все равно понадобится конечный разделитель или просто сохраните синтаксис до EOF, поскольку иload
, иcompile-file
связывают*readtable*
вокруг обработки файла. И да, DSL в Лиспе легко использовать с синтаксисом s-expr (или, скорее, читабельным синтаксисом Лиспа), но в остальном требуется синтаксический анализатор, как и в любом другом языке. Вы должны взвесить (не)преимущества и посмотреть, соответствует ли это вашим потребностям. - person acelent   schedule 16.07.2015compile
илиcompile-file
. Я помню, как делал это для AST пользовательского языка (в стиле C lex&yacc), и он не только работал, он работал так хорошо, что я мог сравнивать результаты с скомпилированным машинным языком. - person acelent   schedule 17.07.2015