Как да дефинирам макрос за нотация на инфикс в Lisp, без да го затварям в Lisp като синтаксис [затворен]

Така че след като гледах 3 часа видеоклипове в YouTube и прекарах също толкова дълго в четене за Lisp, все още не съм виждал тези „вълшебни макроси“, които позволяват на човек да пише 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

Ако това не е възможно в Lisp, тогава за какво е целият този шум? Това е нещо като да кажете "имате страхотни мощни макроси, които позволяват готини 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 вероятност да навреди на някого - с изключение на няколко KB в SO DB. Защо да бъдете толкова обструктивни? Мислиш ме за мързелив и глупав и искаш да ме накажеш - но защо? Дори и да съм мързелив и глупав, каква болка ви причинява да позволите публикацията ми да остане отворена?   -  person samthebest    schedule 15.07.2015
comment
@samthebest Щетите са добре дефинирани, много реални и са обсъждани ad nauseam. meta.stackoverflow.com/questions/ 254358/   -  person meagar    schedule 15.07.2015
comment
Какво ще кажете да го преместите в Софтуерно инженерство? Мисля, че това е подходящият сайт за този вид насочени и конкретни дискусии, които не са директно фокусирани върху кодови фрагменти и решения.   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira Не. Ако е твърде широко за Stack Overflow, вероятно е твърде широко за програмисти. Ние не водим дискусии.   -  person Thomas Owens    schedule 15.07.2015
comment
@ThomasOwens, не съм съгласен. Както се вижда ясно на помощния сайт на SO и Сайт за помощ на програмисти, обратното е. Този въпрос изглежда попада точно в темата на програмиста: софтуерна архитектура и дизайн.   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira Не казах, че не е по темата. Казах, че е твърде широко. За мен това се чете като начало на дискусия, а не като въпрос за разбиране на концепция или решаване на проблем. Тъй като съм модератор на Програмисти, мисля, че имам доста добра идея какво ще бъде затворено, ако бъде публикувано там.   -  person Thomas Owens    schedule 15.07.2015
comment
@ThomasOwens, добре, но това не трябва да е дискусия, директен отговор като прав си, DSL в Lisp са ясни, стига синтаксисът да е базиран на s-изрази. От моя гледна точка някой с опит може да отговори без обсъждане. Някой друг да се въздържи от отговор. Тоест въпросът наистина не е за размахване на ръка, а по-скоро за опровержение, друго е. И както казах, може да няма опровержение, операцията може да е правилна.   -  person acelent    schedule 15.07.2015
comment
@samthebest, от друга страна, тонът на публикацията може (и трябва) да бъде по-учтив. Например, обърнете внимание на всички главни букви NOTs, цитиране на магически макроси, когато можете просто да споменете макроси, думи като fluff и суетене...   -  person acelent    schedule 15.07.2015
comment
@PauloMadeira помислете, че Томас е модератор в програмистите, по-добре внимавайте, когато казва, че там не е добре. Вижте За дискусиите и защо те не създават добри въпроси. Препоръчително четене: Какво става на Programmers.SE? Ръководство за Stack Overflow   -  person gnat    schedule 15.07.2015
comment
@gnat, добре, напълно съм съгласен с мотивите зад тези ЧЗВ. Предпочитам да бъда насочен към тях (или подобно съдържание) от самото начало. Апелации към авторитет просто ме оставят на тъмно. Заявяване на неща като аз (или той/тя) знам(ите) по-добре от теб е невалидно за мен, освен ако не е подкрепено и с доклади за опит. И звучи доста снизходително. Но все пак, благодаря и на двамата, че изчистихте това вместо мен, тъй като направих същата грешка (предлагайки преминаване към програмисти при подобни условия) веднъж или два пъти в миналото.   -  person acelent    schedule 15.07.2015
comment
OMG, наистина не ме интересува толкова, просто го затворете и няма да използвам Lisp.   -  person samthebest    schedule 16.07.2015
comment
@samthebest, можете да дефинирате макрос, който се разширява до eval-when форма от най-високо ниво, която включва :compile-toplevel и/или :load-toplevel, което тяло променя текущия *readtable* на такъв, който може да чете инфиксна нотация. Все още ще ви е необходим краен разделител или просто пренесете синтаксиса до EOF, тъй като и load, и compile-file свързват *readtable* около обработката на файлове. И да, DSL в Lisp са лесни, като се има предвид синтаксис s-expr (или по-скоро четим синтаксис на Lisp), но иначе изискват анализатор, както във всеки друг език. Трябва да прецените (не)предимствата и да видите дали това отговаря на вашите нужди.   -  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)


Разбира се, можете да имплементирате това, за което говорите, в Lisp.

Една голяма разлика между Lisp и другите езици е, че нищо не е фиксирано и вие контролирате какво прави читателят с всеки един знак от входния изходен код. Буквално.

Помислете например за проекта CL-Python и неговия режим Lisp/Python със смесен синтаксис.

По принцип в този режим, ако това, което въвеждате, започва с отворена скоба, тогава се счита за Lisp, в противен случай се счита за Python (включително многоредови конструкции).

...ВЪПРЕКИ ТОВА...

този вид макро/четец-макро библиотека се внедрява рядко, тъй като едно от основните предимства на подхода на s-израз е, че е добре композируем и можете да изграждате други макроси върху съществуващи макроси, повишавайки нивото на езика.

След като се изостави редовността на подхода на s-израз, писането на макроси става досадно, защото за да напишете код, който манипулира код, трябва да имате предвид няколко различни конструкции на езика, правила за приоритет, специални правила, специални синтактични форми.

Езиците, които не са базирани на s-израз, понякога осигуряват реална способност за обработка на макроси, но работят на ниво AST, т.е. след като някои анализиращи обработки вече са извършени по фиксиран начин. Освен това кодът на макроса в тези езици изглежда наистина странен, защото кодът, който макросът манипулира, проверява или изгражда, не изглежда като истински код.

Понякога на други езици вместо това можете да намерите само текстови макроси, които основно са заменени с търсене. За да видите пример за това колко грозни могат да станат нещата, разгледайте стандартната библиотека на Python изпълнение на collections.namedtuple (около ред 284) и неговия набор от абсурдни ограничения, предизвикани само поради това изпълнение.

Друг пример за това как нещата могат да станат ужасно сложни, след като се принудите да използвате подход само с шаблон, за да избегнете сложността на манипулирането на неправилен и специален език с регистър, е C++ шаблонно метапрограмиране.

Вместо това прост език, базиран на s-израз и квази-цитиране, прави макро кода много по-лесен за писане, четене и разбиране и затова кодът на Lisp не се отдалечава от него. Не защото не може, а защото няма смисъл да се преминава към по-лош синтаксис без причина.

В Lisp вие "огъвате" езика малко, като добавяте абстракциите, които наистина са необходими, без обаче да нарушавате всичко останало и най-важното, без да изпускате способността да правите повече огъване в бъдеще, ако е необходимо. Писането на макрос/макрос за четене, който прави израза да анализира кошмара на да кажем C++ и в същото време премахва възможността за писане на допълнителни макроси и добавяне на повече конструкции (или го прави невероятно трудно), би било безсмислено самоубийство.

Дори макрос като (infix x + y * z) е просто упражнение... Съмнявам се, че някой lisper би го използвал, за да напише истински код... защо, за бога, някой ще въведе отново абсурдната двойственост функция/оператор и кошмара на правилата за приоритет/асоциативност? Ако не харесвате Lisp, просто не използвайте Lisp.

За лиспер не частта (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