Как определить макрос инфиксной нотации в Лиспе, не заключая его в синтаксис, подобный Лиспе

Так что, посмотрев 3 часа видео на YouTube и потратив столько же времени на чтение о Лиспе, я еще не видел этих "волшебных макросов", которые позволяют писать DSL или даже делать такие простые вещи, как 4 + 5 без вложение этого внутри некоторых фигурных скобок.

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

Итак, вот задача: определить инфиксный макрос, а затем использовать его без необходимости заключать его в какой-то дополнительный синтаксис. т.е.

Some macro definition here

1 + 2

НЕТ

Some macro definition here

(my-macro 1 + 2)

НЕТ

Some macro definition here

ugly-syntax 1 + 2 end-ugly-syntax

Если это невозможно в Лиспе, то о чем весь этот шум? Это все равно, что сказать: «У вас есть потрясающие мощные макросы, которые позволяют создавать классные DSL, при условии, что эти DSL обернуты в синтаксис, подобный Lisp».


person samthebest    schedule 14.07.2015    source источник
comment
Я не думаю, что это возможно. Базовый синтаксис кода на самом деле не настраивается. Вам нужен какой-то способ сообщить ему, чтобы начать обработку выражения, используя ваш альтернативный синтаксис, и когда остановиться, и для этого требуется какая-то оболочка.   -  person Barmar    schedule 14.07.2015
comment
Stackoverflow не предназначен для публикации задач по программированию. Это для реальных проблем программирования, лучше всего с некоторым кодом, примером использования и описанием ошибки. Stackoverflow говорит: «Сосредоточьтесь на вопросах о реальной проблеме, с которой вы столкнулись. Включите подробную информацию о том, что вы пробовали и что именно вы пытаетесь сделать».   -  person Rainer Joswig    schedule 14.07.2015
comment
Тогда вам придется заменить весь синтаксис Lisp этим макросом (что совершенно нормально и очень распространено).   -  person SK-logic    schedule 15.07.2015
comment
Вы написали: «Итак, вот задача: определить инфиксный макрос...». что ты уже испробовал? Синтаксис? Код? Примеры? С какими проблемами вы столкнулись при синтаксическом анализе выражений? Поскольку вы разместили вопрос, он самоуверен, слишком широк, бесполезен ... Я думаю, что Stackoverflow лучше всего, когда реальные проблемы с кодом получают ответы с большим количеством кода. Вещи, которые на самом деле помогают людям решать настоящие проблемы программирования.   -  person Rainer Joswig    schedule 15.07.2015
comment
@RainerJoswig Это не самоуверенно, это очень хорошо определено, дайте мне способ определить макрос, который мне не нужно заключать в какую-то содержащую область. Я пока ничего не пробовал, потому что в Интернете нет ничего, объясняющего, как это сделать, первый комментарий кажется правильным - это просто невозможно - это был бы принятый ответ. В любом случае, мой вопрос был не в том, как бы вы хотели, чтобы вопросы выглядели, а в том, если они не соответствуют вашему идеалу, что самое худшее может случиться с вами. В SO есть много педантов, которым нечего делать, кроме как пытаться помешать другим людям учиться. ...   -  person samthebest    schedule 15.07.2015
comment
@RainerJoswig Если этот вопрос будет закрыт, что вы получите? Какой ущерб был нанесен, если оставить открытым? Если бы кто-то на самом деле предоставил код для ответа на мой вопрос, наверняка это облегчило бы будущим сотрудникам Google изучение Lisp? Вероятность 1,0, что это поможет мне, и вероятность 0,0, что это навредит кому-либо, кроме нескольких КБ в SO DB. Зачем так тормозить? Ты считаешь меня ленивым и глупым и хочешь меня наказать - но за что? Даже если я ленивый и глупый, какой вред причиняет вам то, что мой пост остается открытым?   -  person samthebest    schedule 15.07.2015
comment
@samthebest Ущерб четко определен, очень реален и обсуждался до тошноты. meta.stackoverflow.com/questions/ 254358/   -  person meagar    schedule 15.07.2015
comment
Как насчет того, чтобы перенести его в раздел Разработка программного обеспечения? Я думаю, что это подходящий сайт для такого рода направленных и конкретных дискуссий, не сосредоточенных непосредственно на фрагментах кода и решениях.   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira Нет. Если он слишком широк для переполнения стека, он, вероятно, слишком широк для программистов. Мы не занимаемся дискуссиями.   -  person Thomas Owens    schedule 15.07.2015
comment
@ThomasOwens, позволю себе не согласиться. Как видно на справочном сайте SO и Сайт помощи программистам, все наоборот. Кажется, этот вопрос относится к теме программиста: архитектура и дизайн программного обеспечения.   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira Я не говорил, что это не по теме. Я сказал, что это слишком широко. Для меня это звучит как начало дискуссии, а не как вопрос о понимании концепции или решении проблемы. Так как я модератор на Programmers, я думаю, что у меня есть довольно хорошее представление о том, что будет закрыто, если опубликовать там.   -  person Thomas Owens    schedule 15.07.2015
comment
@ThomasOwens, хорошо, но это не обязательно должно быть обсуждение, прямой ответ, например, вы правы, DSL в Lisp просты, если синтаксис основан на s-выражениях. С моей точки зрения, человек с опытом может ответить без обсуждения. Кто-то другой должен воздержаться от ответа. То есть вопрос действительно напрашивается не для маханья руками, а скорее для опровержения, это другое. И как я уже сказал, опровержений может и не быть, оп может быть прав.   -  person acelent    schedule 15.07.2015
comment
@samthebest, с другой стороны, тон сообщения мог бы (и должен) быть более вежливым. Например, обратите внимание на NOT в верхнем регистре, заключающие в кавычки магические макросы, когда вы могли бы просто упомянуть макросы, такие слова, как fluff и суета...   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira считает, что Томас является модератором в Programmers, вам лучше обратить внимание, когда он говорит, что там не все в порядке. См. раздел Об обсуждениях и о том, почему они не вызывают хороших вопросов. Рекомендуемая литература: Что происходит на Programmers.SE? Руководство по переполнению стека   -  person gnat    schedule 15.07.2015
comment
@gnat, хорошо, я полностью согласен с рассуждениями, лежащими в основе этих часто задаваемых вопросов. Я бы предпочел, чтобы мне указали на них (или подобный контент) с самого начала. Апелляции к властям просто оставьте меня в неведении. Заявления вроде Я (или он/она) знаю(а) лучше вас для меня недействительны, если только они не подкреплены отчетами об опыте. И это тоже звучит довольно снисходительно. Но в любом случае, спасибо вам обоим за то, что разъяснили мне это, так как я совершал ту же ошибку (предлагая перейти программистам на аналогичных условиях) один или два раза в прошлом.   -  person acelent    schedule 15.07.2015
comment
О боже, мне на самом деле все равно, просто закройте его, и я не буду использовать Лисп.   -  person samthebest    schedule 16.07.2015
comment
@samthebest, вы можете определить макрос, который расширяется до формы eval-when верхнего уровня, которая включает :compile-toplevel и/или :load-toplevel, тело которой изменяет текущий *readtable* на тот, который может читать инфиксную нотацию. Вам все равно понадобится конечный разделитель или просто сохраните синтаксис до EOF, поскольку и load, и compile-file связывают *readtable* вокруг обработки файла. И да, DSL в Лиспе легко использовать с синтаксисом s-expr (или, скорее, читабельным синтаксисом Лиспа), но в остальном требуется синтаксический анализатор, как и в любом другом языке. Вы должны взвесить (не)преимущества и посмотреть, соответствует ли это вашим потребностям.   -  person acelent    schedule 16.07.2015
comment
@PauloMadeira Большое спасибо! Не могли бы вы привести пример?   -  person samthebest    schedule 16.07.2015
comment
Я действительно не могу, у меня его нет, и потребуется некоторое время, чтобы его изготовить. Такая читаемая таблица была бы действительно запутанной, вплоть до того момента, когда я бы предпочел использовать правильный синтаксический анализатор для DSL вместо того, чтобы подрывать читатель Common Lisp. В Lisp есть еще более простая часть: превратить AST в код Lisp и передать его на compile или compile-file. Я помню, как делал это для AST пользовательского языка (в стиле C lex&yacc), и он не только работал, он работал так хорошо, что я мог сравнивать результаты с скомпилированным машинным языком.   -  person acelent    schedule 17.07.2015


Ответы (1)


Конечно, вы можете реализовать то, о чем говорите, на Лиспе.

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

Рассмотрим, например, проект 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
comment
// Также почему вы думаете, что 2+3*6 естественно равно 20? // Математика имеет огромное количество различных типов обозначений... она не ограничивается только инфиксом и постфиксом, рассматривает суммирование или пределы, или нотацию построителя множеств, или матрицы, теоретико-категориальные диаграммы. Математики даже помещают функции и переменные друг над другом — разными шрифтами. Вопрос не в том, что естественно, а в том, как эффективно общаться. Когда кто-то помещает оператор в середину, он сообщает, что это алгебраическая операция, .... - person samthebest; 15.07.2015
comment
.... и вполне вероятно, что можно предположить алгебраические свойства. Когда функции помещаются выше своих аргументов, подразумевается, что аргумент представляет собой последовательность. Чем больше возможностей у языка, тем эффективнее он может общаться — если язык не может ЛЕГКО поддерживать несколько нотаций, тогда он не может эффективно общаться и никогда не получит широкого распространения. В любом случае, этот пост не должен был открывать дискуссию, я искренне хотел знать, как это сделать, потому что кто-то сказал мне, что я должен использовать Lisp, потому что я пишу свой собственный компилятор макросов для LaTeX. - person samthebest; 15.07.2015
comment
@samthebest: В математике, когда вы видите a×b, вы можете очень мало угадать, поскольку это зависит от контекста. Это может быть внутренняя операция или нет (например, векторное произведение в ℝ²), оно может быть коммутативным или нет (векторное произведение, умножение матриц). Что довольно часто верно, так это то, что операция ассоциативна (но это все же неверно в общем случае). На самом деле вы знаете не намного больше, чем то, что данное a и b возвращает что-то еще в каком-то пространстве. Это просто функция с двумя переменными. - person 6502; 18.07.2015
comment
Это не то, чему меня учили, когда я получил степень бакалавра по чистой математике или аспирантуру. Обозначение означает ОГРОМНУЮ сумму в математике, я не знаю, как вы могли это отрицать, но в своем собственном комментарии вы используете R ^ 2, прекрасно зная, что это означает нечто совершенно отличное от R_2. Да, теория групп начинается с ассоциативности... - person samthebest; 18.07.2015
comment
Инфикс действительно подразумевает алгебраическую структуру, постфикс подразумевает произвольную функцию. Символы асимметричного инфиксного отношения подразумевают транзитивность и т. д. Да, нужно математическое доказательство, прежде чем можно будет действительно быть уверенным в каком-либо из этих свойств, но это не нотация для, нотация и язык в целом предназначены для сообщения, а не для доказательства утверждений. . Большинство математических доказательств в учебниках даже не формальны, они сообщают доказательство, читатель должен проделать в уме большое количество шагов. - person samthebest; 18.07.2015
comment
... чем выше способность использовать многие конструкции, обозначения, звуки, символы, символы и т. д., тем выше выразительность языка. Это тривиально верно — больше символов означает, что больше информации можно упаковать в меньшее количество байтов. Следовательно, языки, которые допускают большее количество конструкций, общаются больше и эффективнее, в результате они становятся более популярными, потому что для чтения и письма на этих языках требуется меньше усилий. Программист компилятора, с другой стороны, хочет наименьшее количество конструкций/функций, потому что меньше функций означает меньше работы и более быстрые компиляторы. - person samthebest; 18.07.2015
comment
(Извините за расширенные комментарии, последний я обещаю). Наконец, правила приоритета тоже хороши, они тоже могут передавать информацию. Приоритет в математике обычно определяется сложностью функции. Символы, которые определены в терминах других символов, применяются перед этими символами, например, * применяется перед +, потому что он определен в терминах +, аналогично / определяется в терминах *, поэтому применяется раньше, аналогично со ^ и т. д. . Причина, по которой это отстой в школе, заключается в том, что школы отстой, когда вы изучаете это на уровне степени, это становится мощным и крутым! - person samthebest; 18.07.2015