Добрый день всем!
«В свое „оправдание“ могу только сказать, что не люблю такой неортогональный
синтаксис и такую тонкую семантику: откаты вроде бы и есть, а вроде бы их и
нет.»
Я бы не назвал такой синтаксис неортогональным. Здесь важно понять логику языка.
Рефал-5 является относительно консервативным расширением базисного Рефала.
Семантика определяется через понятие поля зрения, в котором активный вызов по
очереди заменяется на некоторое выражение. И эту семантику Турчин
последовательно блюдёт.
В Рефале-5 предложения состоят из левой и правой части: если сопоставление с
левой частью успешно, то управление безальтернативно передаётся на правую
часть. Левая часть состоит из образца и нуля и более условий. Правая часть
может быть либо выражением, либо вызовом безымянной функции. Если сопоставление
с такой расширенной левой частью успешно, то активный вызов заменяется на
результат вычисления правой части. Таким образом, предложение в общем виде
выглядит так:
P where R1 : P1 where R2 : P2 = R;
P where R1 : P1 where R2 : P2 with R : { … };
Откаты в Рефале-5 могут быть только в левой части и могут порождаться и
перехватываться только образцами. К слову, о семантике поля зрения — у Турчина
для каждого условия порождается новое вспомогательное поле зрения, которое
разрушается или после успешного сопоставления, или после неуспешного
сопоставления.
ИМХО, недостаток дизайна языка в том, что Турчин для where- и with-конструкций
выбрал один и тот же знак — запятую. Это и усложняет синтаксический разбор
(прочитав «, выражение», не знаешь — это продолжается левая часть или уже
началась правая). Этот недостаток дизайна был исправлен в некоторых потомках: в
Рефале-7 Скоробогатова <https://bmstu-iu9.github.io/Skorobogatov-Refal-7.pdf>
используются знаки «−>» и «=>» (хотя, на самом деле Рефал-7 построен на основе
Рефала-6, а не Рефала-5), в Рефале-5λ рекомендуется вместо запятой использовать
знак равенства, хотя запятая из соображений совместимости тоже поддерживается.
Впрочем, у Турчина равенство в роли with-знака использоваться не может исходя
именно из логики. Равенство означает факт замены вызова функции в поле зрения
на результат вычислений, но эта замена выполняется не когда вызывается
вложенная функция, а когда она завершается. Для реализации вызовов вложенных
функций у Турчина опять привлекается вспомогательное поле зрения, но это уже,
ИМХО, артефакт реализации.
Разделение логики и дизайна у меня вызвало ассоциации с реализацией Рефала-5λ.
Компилятор сначала переводит
<https://bmstu-iu9.github.io/refal-5-lambda/B-reference.html#%D1%80%D0%B0%D1%81%D1%81%D0%B0%D1%85%D0%B0%D1%80%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5>
входной язык в более бедный внутренний язык, а затем на уровне внутреннего
языка реализуются все оптимизации и генерация кода. Дамп поля зрения при ошибке
тоже выражен в терминах внутреннего языка. Поэтому при программировании на
Рефале-5λ важно знать, во что он сначала упрощается.
На сколько я знаю, примерно также официально определяется семантика ML.
«Напомню, что идею такой системы еще с 90-х пропагандирует Сергей Абрамов и
инициировал такой рефал-проект, который, к сожалению, пребывает в замороженном
состоянии (его участники, напомните web-ссылку)).»
Если речь идёт об универсальном абстрактном синтаксическом дереве, в которое
нужно компилировать разные диалекты Рефалов, то web-ссылка умерла. Описание
этого синтаксиса было на wiki, которую админы botik.ru отключили.
«Кстати, о сравнении Рефала Плюс Сергея Романенко с Рутеном Гуриным и Рефала-6
в версии Аркадия.»
Всё же я склоняюсь к тому, что замкнутость относительно суперкомпиляции была
одной из целей разработки Рефала Плюс. Важным понятием при трансформациях
являются присваивания (S :: He R) и перестройки (S : Snt), поэтому звенья вида
«выражение+образец» должны быть базовыми понятиями языка. Образцы в начале
предложений и последние источники в них тоже в некотором смысле являются
звеньями «выражение+образец»: для образцов в начале неявной левой частью звена
оказывается аргумент функции [ARG] : Pat, для последних источников неявной
правой частью — результат функции S :: [RES].
В Рефале-6 цели замкнутости относительно суперкомпиляции не было, поэтому можно
было упростить синтаксис, введя понятие действия. Образцовое действие —
образцовое выражение, которое сопоставляется с неявным «аргументом».
Результатное действие — результатное выражение, которое при вычислении
подменяет аргумент.
Рефал Плюс можно транслировать в Рефал-6, Рефал-6 можно транслировать в Рефал
Плюс. Если транслировать Рефал Плюс в Рефал-6, то звенья «выражение+образец»
будут парой отдельных действий — результатного и образцового. Если
транслировать Рефал-6 в Рефал Плюс, то наоборот действия нужно будет неявно
переводить в такие звенья.
С Днём Победы всех! Мирного неба над головой!
С уважением,
Александр Коновалов
From: Andrei Klimov andrei_AT_klimov.net <[email protected]>
Sent: Sunday, March 28, 2021 10:12 PM
To: [email protected]
Subject: О разделении логики и дизайна
[Сменил сабж, так как "Остапа понесло".]
On Sun, Mar 28, 2021 at 8:31 PM Александр Коновалов a.v.konovalov87_AT_mail.ru
<http://a.v.konovalov87_AT_mail.ru> <[email protected] <mailto:[email protected]> >
wrote:
Добрый вечер, Андрей!
В Рефале-5 запятая для откатов прозрачна. Не прозрачны для откатов только
фигурные скобки — блоки после двоеточия и сами вызовы функций. Поэтому
результатное выражение после запятой неуспеха породить не может (по
определению), а образец после двоеточия — запросто.
Синтаксис «, выражение : образец» в Рефале-5 есть и он называется
«where-конструкция». Синтаксис «, выражение : {…}» называется
with-конструкцией. Они упоминались не только в учебнике, но и в главах
обнинской школы метавычислений — там вместо запятой используются ключевые слова
where и with соответственно.
Спасибо! Буду иметь в виду. Значит, в нашем разговоре Турчин имел в виду
первое, а я не до конца ухватил и перенес на второе тоже. Значит, логика такая:
* «{...}» – это подставленное тело функции,
* «, выражение :» – это синтаксис для ее вызова,
* «, выражение : образец ...» – это отдельная конструкция со своей
семантикой, отличающейся от «, выражение : { образец ...}».
В свое «оправдение» могу только сказать, что не люблю такой неортогональный
синтаксис и такую тонкую семантику: откаты вроде бы и есть, а вроде бы их и
нет. Скобки вроде бы лишь «объединитель» (как в школьной математике), а вроде
бы и нет. Поэтому и подумал, что Турчин был просто против откатов.
Александр, вы пишете, что понимаете устройство Рефала Плюс как языка, на
котором выразима суперкомпиляция. Формально говоря, да, но как с общей целью я
с этим не согласен. Только ради этого огород не стоило бы городить, создавая
новый язык (хотя это интересно, и возможно, локальным стимулом для Сергея
Романенко было просто естественное желание посмотреть, что получится). Для меня
важен общий принцип «языкостроительства»:
* Формальный язык (будь то язык математики, логики, или язык
программирования) должен быть максимально «ортогонализован»: базовые
семантические единицы явно выражены, а более высокие конструкции собираться из
них. Это обычно называется композиционностью. Такое требование особенно
применимо к метаязыку, предназначенному для описания, конструирования других
языков. (Если сам не композиционен, что можешь предложить другим?)
Но вы (как многие) спросите: А как же быть с удобствами программирования? Мы же
знаем по опыту разных языков, что, когда «всё торчит наружу», язык получается
громоздким, так ведь? И да, и нет. Это уже другой вопрос. Вспоминаю, как
когда-то в 80-е в перерыве рефал-семинара в ИПУ, стояли мы, курили (была такая
вредная привычка и у меня), и тут Николай Кондратьев высказал следующий тезис
(возможно прочитанный в каком-то труде, а может сам красиво сформулировал –
помнит ли он сейчас?):
* Надо тщательно различать логику и дизайн языка программирования. Плохо,
когда они путаются и решения принимаются то в пользу одного, то другого
(типичная ситуация в комитетах по стандартизации языков).
* Логика – это устройство языка, его колесики, его базовые понятия,
правила конструирования, композиция.
* Дизайн – это как язык выражен во внешнем синтаксисе (и вообще, может и
не в одномерном тексте, а, скажем, в projectional
<https://martinfowler.com/bliki/ProjectionalEditing.html> editor
<https://martinfowler.com/bliki/ProjectionalEditing.html> 'е).
* Цель разработки логики языка – чтобы она была композиционна и полна (по
отношению к как можно большему числу разных деятельностей над языком).
* Цель дизайна – чтобы было удобно человеку: в данных исторических
условиях, с данными инструментами создания и чтения программ, которые могут
меняться, да и, вообще говоря, разным человекам нужен разный синтаксис (плохо,
что обычно создаются разные языки для разных профессий типа COBOL для
«бухгалтеров», а PL/I для «профессиональных програмистов», а не один язык с
разными «лицами»).
* Подход к разработке языка должен такой: сначала разрабатываем логику, а
потом, не нарушая ее, отрабатываем дизайн, а лучше – много дизайнов. Здесь
слова «сначало» и «потом» относятся не ко времени, а к приоритетам. Разработка
чего угодно всегда циклична: делаем версию, недовольны, возвращаемся к началу.
Если язык оказался для чего-то плох, подумайте, к чему относится вопрос: только
ли к дизайну? или к логике, а потом и к переработке дизайна под улучшенную
логику?
С этой колокольни я и смотрю на все давние и постоянно возрождающиеся споры о
том, кому какой Рефал нравится. То есть равнодушно с точки зрения дизайна (это
вкусовщина). И с интересом с точки зрения логики. Идеальный метаязык с его
идеальной реализацией должен иметь совершенную логику и возможность задавать
различные дизайны: разные синтаксисы, выделять подмножества для различных целей
и аудиторий, каждое подмножество может иметь свой вид, и т.п. Всё это
многообразие должно описываться на самом Рефале. (Самоприменение, метасистемный
переход.) Напомню, что идею такой системы еще с 90-х пропагандирует Сергей
Абрамов и инициировал такой рефал-проект, который, к сожалению, пребывает в
замороженном состоянии (его участники, напомните web-ссылку)). Его можно было
бы возродить, но уже обязательно на современном уровне, пользуясь современными
инструментами, IDE, современной мощностью компьютеров (не оптимизируя решения
«ради эффективности») и т.п.
Рефал вроде бы «умер». А что могло бы не дать ему умереть в свое время, а может
и теперь возродиться? Когда-то мы фантазировали о том, что хорошо бы найти и
занять какие-нибудь успешные прикладные ниши для Рефала, которые существовали в
годы его расцвета, когда конкурентов ему практически не было, но потом были
заняты другими языками. (Например, до сих пор думаю, что упущенная возможность
– Рефал как скриптовый язык; это непросто, но идеи были, причем мы об этом
думали еще тогда, когда не начался мировой buzz по их поводу). Но каждая ниша –
это частный вопрос, частный успех или неуспех. А быть метаязыком –
конструктором языков – это принципиальное свойство, до сих пор не достигнутое
ни в одном живом языке в желаемом виде.
Кстати, о сравнении Рефала Плюс Сергея Романенко с Рутеном Гуриным и Рефала-6 в
версии Аркадия. Рефал Плюс – это была первая попытка создать
ортогонализированный Рефал. Но Сергей (как он сам тогда говорил) был скован
дополнительным требованием, сильным желанием, чтобы быть как можно ближе к
Рефалу-5 по синтаксису. Отсюда возникали решения, чтобы, когда семантика
одинакова, то синтаксис был бы тот же или понятно, как соотносился. Помню наши
эмоциональные обсуждения, когда Рефал Плюс был «выдан на гора», и мы приставали
к Сергею: а вот тут бы еще «подвигать», тут бы еще «подкуртить». А Сергей
отвечал: отстаньте, и так уже синтаксис слишком тонко подогнан, тронешь –
замучаешься грамматику для Yacc'a перерабатывать. То есть он максимально
продвинулся по логике, но под давлением совместимости с Рефалом-5 и
использованных инструментов реализации не стал дальше «оптимизировать» язык.
А Аркадий превращал Рефал-6b Николая Кондратьева в свой Рефал-6 позже, уже
опираясь на положительный и отрицательный опыт Рефала Плюс. Неудивительно, что
со второй попытки он добился (на мой взгляд) бóльшей регулярности и логики, и
дизайна, то есть синтаксиса, отражающего логику языка. Базовые «кирпичи»
Рефала-6 чуть помельче, чем у Рефала Плюс. Пользователю это почти не видно, но
сделало проще также и формальную грамматику языка.
Такие дела...
Андрей Климов
С уважением,
Александр Коновалов
От: Andrei Klimov andrei_AT_klimov.net <mailto:[email protected]>
Отправлено: 28 марта 2021 г. в 16:47
Кому: [email protected] <mailto:[email protected]>
Тема: Re: Регулярные выражения слева
On Sat, Mar 27, 2021 at 11:47 PM Александр Коновалов a.v.konovalov87_AT_mail.ru
<http://a.v.konovalov87_AT_mail.ru> <[email protected] <mailto:[email protected]> >
wrote:
[...]
Вариативность (но с ущербом для эффективности) можно реализовать и в Рефале-5.
Код, эквивалентный коду Рефала-6, будет выглядеть так:
F {
e.Name 〈что-то ещё〉, <F-Name e.Name> : T = … ;
… = …;
}
F-Name {
'Маша' = T;
'Саша' = T;
e.Other = F;
}
А разве такое в Рефале-5 можно? С 90-х годов я рефал-плюсовый программист, мог
и забыть. А сейчас лень заглядывать в руководство, да и, думаю, будет полезно
обсудить здесь логики разных Рефалов, из которых вытекают различные решения по
синтаксису. Помнится, подобные вопросы мы специально обсуждали в те годы, и у
меня отложилось, что:
1. Запятая в Рефал-5 "непрозрачна для откатов", то есть "неотож" после запятой
не вызывает возврат к следующему варианту в образце левее или следующему
предложению. Помнится, "длинные" откаты вызывали отторжение у Турчина и у
других апологетов Рефала-5.
2. Синтаксиса вида "выражение : образец" в Рефале-5 нет. Помнится, при
обсуждении расширений Рефала Плюс по сравнению с Рефалом-5, Турчин говорил, что
в Рефале-5 двоеточие означает вызов подставленного тела вспомогательной функции
и только это. Поэтому, даже если в ней только одно предложение, всё равно надо
ставить фигурные скобки, чтобы выглядело одинаково с определением функции. То
есть данный код синтаксически правильно надо писать так (а семантика будет
другая, чем хотелось):
F {
e.Name 〈что-то ещё〉, <F-Name e.Name> : { T = … };
… = …;
}
И уж нечего и говорить, что фигурные скобки в Рефале-5 безоткатные.
Правильно я помню Рефал-5 и его логику?
Андрей