Добрый вечер, Аркадий!
Спасибо за отклик.
> Александр, спасибо, очень приятное, лаконичное и содержательное представление
> достоинств и преимуществ рефала.
Здесь, скорее, не достоинства и преимущества, а черты, отличающие Рефал от
большинства других языков. Будут ли они достоинствами и преимуществами —
спорный вопрос. Та же двунаправленность и конкатенация приводят сложности
эффективной реализации: приходится платить или стоимостью копирования
переменной (на сколько мне известно, эта проблема известна только в Рефале),
или стоимостью конкатенации в зависимости от промежуточного представления.
> Однако сразу отмечу, чего здесь не хватает и что плохо дается.
> 1. Таблицы, словари с быстрой выборкой по ключу (можно сделать внешними
> средствами, но это выглядит как чужеродный объект).
У меня были мысли, как расширить синтаксис Рефала для поддержки словарей —
напишу отдельным письмом (позже, возможно, завтра).
> 2. Я не смог придумать, как удобно сделать разметку дерева дополнительной
> информацией, чтобы она не мешала анализу, например, чтобы парсер добавил
> информацию о позициях (строка, колонка) в исходном файле. В ОО-среде это было
> бы тривиально, через дополнительные скрытые атрибуты.
Можно, используя условия:
/*
t.Expr ::=
(t.Pos Ident e.Name)
| (t.Pos Const e.Value)
| (t.Pos t.Expr s.BinOp t.Expr)
| …
t.PureExpr ::=
(Ident e.Name)
| (Const e.Value)
| (t.Expr s.BinOp t.Expr) -- намеренно нерекурсивно!
| …
*/
// <Pure t.Expr> == t.PureExpr -- нерекурсивная!
Pure { ... }
SomeParserFunc {
… t.Expr …
, <Pure t.Expr> : (Name e.VarName)
…
}
Немного многословно (есть некоторое количество синтаксического шума), но
работать будет. Можно для этой идиомы придумать какой-нибудь синтаксический
сахар, в котором будет меньше синтаксического шума — по аналогии с
экстракторами в Scala (см. метод unapply). Скажем, как-то так:
SomeParserFunc {
… t.Expr @ <Pure (Name e.VarName)> …
}
Т.е. запись
… VAR @ <EXTR PATTERN> …
является сокращённой записью
… VAR …, <EXTR VAR> : PATTERN
неуспех в экстракторе EXTR приводит к неуспеху образца. Если не нравятся
угловые скобки в образце, можно использовать квадратные:
… VAR @ [EXTR PATTERN] …
С уважением,
Александр Коновалов
Отправлено из Mailspring (https://getmailspring.com/), лучшего бесплатного
приложения электронной почты
On нояб. 5 2024, at 7:44 вечера, Arkady Klimov arkady.klimov_AT_gmail.com
<[email protected]> wrote:
> Здравствуйте все!
> Александр, спасибо, очень приятное, лаконичное и содержательное представление
> достоинств и преимуществ рефала.
> Очень мне понравилось Ваше выражение: "без лишнего синтаксического шума". Это
> очень точно сказано.
> Я последнее время изучаю язык Julia, там тоже есть сопоставление с образцами,
> правда не в самом языке, а в виде библиотеки. Но точно с излишним
> "синтаксическим шумом".
> В Julii образцы тоже двусторонние, есть повторные переменные, вложения
> образцов, переменные типа "список" с эллипсисом, но открытых переменных нет
> (с поиском подобразца в списке). Есть даже управление откатами.
> Об областях применения. Ваш пример хорош, подобное мне тоже приходилось
> писать. Наверно можно сказать шире: любая трансляция из синтаксического
> дерева в другое дерево или что-то еще. Действительно, рефал дает очень хорошо
> читаемое представления АСД. Однако сразу отмечу, чего здесь не хватает и что
> плохо дается.
> 1. Таблицы, словари с быстрой выборкой по ключу (можно сделать внешними
> средствами, но это выглядит как чужеродный объект).
> 2. Я не смог придумать, как удобно сделать разметку дерева дополнительной
> информацией, чтобы она не мешала анализу, например, чтобы парсер добавил
> информацию о позициях (строка, колонка) в исходном файле. В ОО-среде это было
> бы тривиально, через дополнительные скрытые атрибуты.
>
> Еще применения: мне недавно довелось писать обратный инжиниринг для
> вентильных схем, отображенных в КНФ. Есть КНФ в формате DIMACS, построенная
> по вентильной схеме, требуется восстановить исходную схему. Очень классно
> играют образцы с открытыми переменными при поиске шаблонов - образов
> вентилей. Это все приходилось подбирать в ходе проб, и я не знаю, в каком
> языке это было бы удобнее. Удавалось подняться до весьма сложных элементов
> вроде мультиплексоров, if-then-else, AND-OR-XOR-EQU с многими аргументами.
> При желании можно и сумматоры находить, но я уж выдохся.
> Да, и последующее преобразование результата в формат .dot для Graphviz.
> Думаю, все что угодно инверсно инжинирить удобнее на рефале.
>
> Пока продолжаю использовать рефал для преобразований программ. Поскольку
> изучаю Julia, надеюсь в ближайшем будущем получить опыт написания одного и
> того же преобразования как на рефале, так и на Julia. Посмотрим.
>
> С уважением,
> Аркади
>
>
> вт, 5 нояб. 2024 г. в 16:21, Александр Коновалов a.v.konovalov87_AT_mail.ru
> (http://a.v.konovalov87_AT_mail.ru) <[email protected] (mailto:[email protected])>:
> > Добрый день!
> >
> > Предлагаю порассуждать на тему применимости Рефала сегодня: какие у него
> > могут быть преимущества перед другими языками и как ими можно
> > воспользоваться.
> > Я могу выделить следующие черты Рефала:
> > дина��ически типизированный с закрытым набором типов — есть ограниченный
> > набор встроенных типов данных, пользовательские типы конструируются на
> > уровне соглашений (исключение: пара моих реализаций, где есть
> > инкапуслирующие квадратные скобки — небесспорное расширение) — примерно та
> > же ситуация, что и в классической Scheme;
> >
> > мощное сопоставление с образцом — сопоставлением с образцом сейчас уже
> > никого не удивишь, оно есть даже в Питоне (начиная с версии 3.10 или 3.11,
> > и тоже довольно выразительное), но есть две достаточно редкие черты:
> > повторные переменные, и соответственно, встроенное в язык понятие равенства
> > (однако, есть в Racket и есть в Scala),
> >
> > поиск в середине последовательности по образцу «e.X PAT e.Y», аналогичная
> > возможность есть только в Tom (https://tom.loria.fr/) (предназначен для
> > работы с XML и вообще удивительно похож на Рефал);
> >
> >
> >
> > встроенная в семантику конкатенация — в результатных выражениях она
> > записывается пустым местом, в других языках синтаксис конкатенации более
> > многословный,
> >
> > симметричный доступ к обоим концам последовательности в образцах — в
> > большинстве функциональных языков встроенными (основными)
> > последовательностями являются однонаправленные списки и образцы допускают
> > обращение только слева, исключения — Scala, где есть «:+» и «+:»,
> > сопоставление с эллипсисом в макросах Scheme и образцах Racket, образцы в
> > Python, но там списки — массивы,
> >
> > возврат из функции нескольких значений столь же (не)естественнен, как и
> > передача нескольких аргументов.
> >
> >
> >
> > Подытоживая, Рефал — динамически типизированный функциональный язык с
> > выразительным сопоставлением с образцом, позволяющий удобно преобразовывать
> > иерархические данные, например, синтаксические деревья. И сами данные, и их
> > сопоставление с образцом, и построение новых значений записываются без
> > лишнего синтаксического шума, т.е. всевозможных запятых, значков «+», «++»,
> > «+:» и прочих. Благодаря динамической типизации, он годится для быстрого
> > написания небольших программ, выполняющих символьные вычисления. Но с
> > другой стороны, написание крупных программ, разрабатываемых коллективами
> > затрудняется: типы всё равно придётся определять и документировать, что для
> > Рефала, как правило, делается комментариями с грамматикой для объектных
> > выражений.
> > Я пока нашёл только одну сферу, где Рефал неплох и абсолютно уместен —
> > рабочий язык для небольшого курса, посвящённого генерации кода. Студенты
> > пишут программы, принимающие на входе синтаксическое дерево, и порождающие
> > код для модельного ассемблера. Пример синтаксического дерева:
> >
> > (function gcd (x y)
> > (var (rem 1))
> > (while ((L y) "<>" 0)
> > (rem "=" ((L x) "%" (L y)))
> > (x "=" (L y))
> > (y "=" (L rem))
> > )
> > (return (L x))
> > )
> > Синтаксическое дерево одновременно выглядит как код на ЯП и одновременно
> > машиночитаемо — это просто запись объектного выражения Рефала-5. Синтаксис
> > Рефала и основные приёмы программирования можно рассказать за две пары, а
> > затем уже студенты могут писать компиляторы для подобных программ в рамках
> > домашних работ. Более подходящего языка для этого курса я не вижу.
> >
> >
> > Других применений, где Рефал уместнее других языков программирования, я
> > пока не встречал. А вы?
> > Где ещё Рефал может быть уместнее других языков программирования?
> >
> > С уважением,