Добрый день, Василий!

Такая технология мне понятна, но речь идет о простоте в использовании для 
"рядового" программирования. Кроме того в больших проектах не навставляешься 
таких строк. Их как раз может добавлять суперкомпилятор при подготовке 
программы к исполнению.


>Среда, 18 декабря 2019, 10:36 +03:00 от Stelletsky V <s...@cnshb.ru>:
>
>Добрый день!
>Александр! Есть 3-й самый простой вариант: добавляете в проблемную функцию еще
>одно (или больше) предложение – вот Вам и обработка неуспеха! Если они что-то
>выводят – можете проанализировать «листинг»…
>Я, например, после «сложных» программ, которые могут «свалиться» делаю проверку
>на наличие «дампа» и в этом случае останавливаю выполнение  bat -файла,
>а то и шлю себе на почту сообщение об аварии…
> 
>С уважением,
>Василий Стеллецкий
>--
>Vasily Stelletsky   mailto:s...@cnshb.ru     mailto:sw...@ya.ru
>http://www.cnshb.ru/vniitei/sw/     http://sw710.narod.ru
>----------------------------------------------------------------------
>From: Александр Гусев
>gusev_aleksandr_AT_mail.ru [mailto:refal@botik.ru] 
>Sent: Wednesday, December 18, 2019
>9:44 AM
>To: refal@botik.ru
>Subject: Re: Прогонка по Турчину и
>неуспехи
> 
>Доброго утра!
>
>Вопрос с неуспехами очень важен по-моему, просто краеугольный вопрос. Все
>современные языки включают в себя такие средства, поскольку они существенно
>повышают производительность труда программистов.
>
>Предлагаю взглянуть на всё с практической точки зрения. Что нужно, чтобы
>обучить с нуля и посадить программировать но Рефале 20-30-100 человек для
>решения практических задач. Проблема обработки неуспехов тут на очень важном
>месте, поскольку самая продвинутая программа может "упасть" из-за
>оплошности в одной вроде бы незначащей функции. И сложность поиска решения мало
>зависит от сложности и важности этой функции.
>
>Напрашиваются два решения: 
>1. либо расширять язык обработкой неуспехов, что приведёт, скорее всего, к
>возрастанию сложности понимания языка;
>2. либо пытаться решить проблему средствами суперкомпиляции, либо исправляя
>"сомнительные" места, либо на них указывая. Это сильно сложнее, но
>зато скрыто от пользователя - вполне заурядного программиста и ему сильно
>легче.
>
>Сейчас ни тот ни другой путь ещё не пройден до конца, как я думаю.
>
>Интересно, есть ли ещё варианты?
>
>Да, мне кажется, что базисный Рефал - это минимум, ниже которого опускаться не
>следует. Это сильно сужает гибкость языка и может служить только чисто
>теоретическим целям.
>Среда, 18 декабря 2019,
>1:16 +03:00 от Александр Коновалов a.v.konovalov87_AT_mail.ru
>< refal@botik.ru >:
>Доброй ночи всем!
>Пришло
>в голову одно интересное соображение. Но сначала контекст.
>В 1974 году
>Турчин описал прогонку как эквивалентное преобразование программы
>на Рефале ( Москва: ЦНИПИАСС, 1974 ( pdf ) ).
>На самом деле прогонка была описана на два года раньше ( Киев-Алушта, 1972 ( 
>pdf ) ),
>но там термина «прогонка» ещё не было.
>В этих
>работах описывается подмножество базисного Рефала —  ограниченный Рефал , в 
>котором
>в образцах запрещены любые  t -переменные
>и открытые и повторные  e -переменные.
>Для этого подмножества определена  прогонка  —
>замена одного из предложений функции  F ,
>содержащей вызов функции  G  на эквивалентный
>набор предложений (в том числе и пустой), в которых вызов  G отсутствует. При 
>этом семантика функции  F на исходной области определения не меняется.
>Однако, область определения функции  F  при этом
>может расшириться — если ранее программа вылетала с ошибкой
>невозможности отождествления, то после прогонки одного из вызовов
>функции программа может перестать падать (вместо чего выдавать какой-то
>результат или зацикливаться).
>Алгоритм прогонки
>я здесь описывать не буду, поскольку он есть в статьях
>по гиперссылкам выше. Лучше читать работу  Киев-Алушта, 1972 ( pdf ) , 
>поскольку
>она короче. Прогонка в ней — правило  EF 1.
>Покажу
>на примере, как прогонка расширяет область определения. Пример простой,
>но расписан подробно,  читать рекомендуется по диагонали.
>Буду использовать
>синтаксис Рефала-5, поскольку мне он более привычен.
>F {
>   A e . Z = 1  e . Z ;
>   s . X e . Z = < G s . X >  e . Z ;
>   t . X e . Z = 100  e . Z ;
>}
>
>G {
>   P =
>10;
>   Q =
>20;
>}
>При прогонке мы
>комбинируем левые части предложений прогоняемой функции  G с левой частью 
>предложения, содержащего вызов
>прогоняемой функции. Сам вызов прогоняемой функции заменяем
>на соответствующие правые части. В результате получится такая функция F :
>F {
>   A e . Z = 1  e . Z ;
>   P e . Z = 10  e . Z ;
>   Q e . Z = 20  e . Z ;
>   t . X e . Z = 100  e . Z ;
>}
>Но, можно
>заметить, что область определения расширилась. Если ранее вызов < F
>X Y Z > падал:
>< F X Y Z > → < G X >  Y Z  → ошибка
>то теперь он
>выдаёт ответ:
>< F X Y Z > → 100  Y Z
>Почему так
>происходит?
>Рассмотрим
>сначала корректный случай, например, < F Q R
>S >.
>До   прогонки :
><F
>Q R S> → <G Q> R S → 20 R S
>В исходной
>функции  F  аргумент
>сопоставится с левой частью второго предложения. Вызов заменится
>на правую часть, где уже будет располагаться вызов < G
>Q >. Для этого вызова применится второе предложение  G ,
>поскольку первое будет неприменимо. Т.е. сначала второе предложение  F ,
>а затем второе предложение  G .
>После прогонки:
>< F Q R S > → 20  R S
>После прогонки
>сразу активируется третье предложение новой функции  F , которое
>является комбинацией исходного второго предложения  F  и исходного
>второго предложения  G . Второе
>предложение новой функции  F  здесь тоже
>будет неприменимо, поскольку оно является комбинацией исходного второго
>предложения и первого предложения функции  G .
>Теперь вернёмся
>к примеру < F X Y Z >.
>До прогонки активировалось второе предложение  F , после
>чего вызов  G  падал, поскольку
>ни одно из его предложений не применимо. После прогонки
>становятся неприменимыми второе и третье предложения новой функции  F (т.к.
>неприменимы их прообразы в  G )
>и управление передаётся на четвёртое предложение.
>Т.е. область
>определения может расширяться на те случаи, где прогоняемый вызов
>должен был падать. (А может и не расширяться, если,
>к примеру, прогоняемый вызов никогда не падает или предложение с этим
>вызовом самое последнее.)
> 
>Теперь
>перехожу к сути письма.
>Условимся, что
>прогонять мы будем только самый первый вызов с пассивным аргументом —
>в этом случае мы избежим нарушения порядка вычислений функций для
>неленивого Рефала. При этом вот ограничении  прогонка
>будет сохранять область определения, если дополнить ограниченный Рефал
>неуспехами.
>Определим такой  ограниченный Рефал-6  — подмножество
>Рефала-6, в котором предложения могут иметь вид « L -образец,
>результат». Т.е. в отличие от базисного Рефала, в ограниченном
>Рефале-6 правая часть отделена от левой  не равенством,
>а запятой .
>Что это даёт.
>Если в Рефале-6 ни одно из предложений функции оказалось
>неприменимо, то программа аварийно не завершается, вместо этого
>функция вырабатывает особое значение — «неуспех». Если функция возвратила
>неуспех в результатном выражении после знака «=», то программа уже
>падает с ошибкой «неперехваченный неуспех». Если неуспех возник
>в результатном выражении после знака «,», то он может быть перехвачен
>и обработан программой. Я здесь не буду подробно описывать семантику
>неуспехов, она есть  в руководстве к Рефалу-6 . Отмечу лишь, что
>в программах ограниченного Рефала-6 управление в случае неуспеха
>будет передаваться на следующее предложение.
>Рассмотрим такую
>программу на ограниченном Рефале-6:
>F {
>  A e.Z , 1 e.Z;
>  s.X e.Z , <G s.X> e.Z;
>  t.X e.Z , 100 e.Z;
>};
>
>G {
>  P , 10;
>  Q , 20;
>};
>Рассмотрим вызов
>< F X Y Z >. Первое предложение  F окажется неприменимо. Применится второе 
>предложение.
>В правой части будет выполняться вызов < G X >. Оба
>предложения функции  G  окажутся
>неприменимы — этот вызов вернёт неуспех. Поскольку правая часть второго
>предложения вернула неуспех, управление будет передано на третье
>предложение. Третье предложение успешно вычислится в 100  Y
>Z .
>Для вызова < F >
>ни одно из предложений  F  окажется
>неприменимо, поэтому такой вызов выработает неуспех.
>Если мы для
>ограниченного Рефала-6 будем применять прогонку, как она описана у Турчина,
>то область определения меняться не будет. Для этого примера мы
>получим:
>F {
>  A e.Z , 1 e.Z;
>   P e.Z , 10 e.Z;
>   Q e.Z , 20 e.Z;
>  t.X e.Z , 100 e.Z;
>}
>Нетрудно
>заметить, что область определения не изменилась. Почему? Если
>до прогонки активировалось второе предложение  F ,
>но ни один из образцов  G  не был
>применим, то вырабатывался неуспех и управление передавалось
>на третье предложение старой  F . После
>прогонки оказываются неприменимы оба новых предложения и управление
>естественным путём передаётся на четвёртое предложение новой  F .
> 
>Неуспехи были
>введены в Рефале-4 ( Романенко, 1987 ( pdf ) ), правда там
>они назывались неудачами. Особенностью Рефала-4 было то, что он замкнут
>относительно операции прогонки, при этом допускает образцы общего вида
>(в отличие от  L -образцов
>в ограниченном Рефале). Позже из Рефала-4 неуспехи перекочевали в Рефал Плюс,
>а оттуда уже в Рефал-6. Поэтому то, о чём я пишу,
>не новость — это должно было быть очевидно Сергею Романенко, когда он
>проектировал Рефал-4 и Рефал Плюс. Когда-то давно разрабатывался
>суперкомпилятор-оптимизатор для Рефала-6. Если в Рефале-6 на тот момент
>уже были неуспехи, то эта особенность прогонки тоже могла быть известна
>авторам суперкомпилятора.
>Так что я
>не претендую на эпохальное открытие, а делюсь, как мне кажется,
>интересным наблюдением.
> 
>Суперкомпилятор
>для ограниченного Рефала будет расширять область определения программы
>по двум причинам. Во-первых, Рефал язык аппликативный,
>а суперкомпилятор реализует ленивую семантику. А вторая причина была
>подробно разобрана в этом письме. И если первая — плата
>за бо́льшую глубину преобразований, то вторую можно преодолеть
>несколькими способами.
>Можно
>в исходных программах использовать только ортогональные образцы +
>условия-неравенства. Любую программу на ограниченном Рефале
>(не ограниченном Рефале-6) можно преобразовать в эквивалентную
>с непересекающимися образцами с условиями-неравенствами.
>Можно
>к каждой функции неявно добавлять предложение вида
>F
>{
>  ...
>  e.X = <F$fail e.X>;
>}
>где  F $ fail  —
>(примитивная) функция, которая падает на любом аргументе. Такие вызовы
>будут падать в остаточную программу ради сохранения области определения.
>Так сделано в оптимизаторе-прогонщике Рефала-5λ (он
>не суперкомпилятор, но прогонка в нём есть).
>И, наконец, можно
>вместо ограниченного Рефала использовать ограниченный Рефал-6. А если
>определить  ограниченный ленивый Рефал-6, то область определения программы 
>будет сохраняться всегда.
> 
>С уважением,
>Александр Коновалов
>
>
>С уважением,
>Александр Гусев
>gusev_aleksa...@mail.ru


С уважением,
Александр Гусев
gusev_aleksa...@mail.ru
  • Про... Александр Коновалов a . v . konovalov87_AT_mail . ru
    • ... Александр Гусев gusev_aleksandr_AT_mail . ru
      • ... Stelletsky V
        • ... Александр Гусев gusev_aleksandr_AT_mail . ru
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru

Ответить