Я тоже начал было писать про "настоящее выворачивание", но Александр меня
опередил.
Да, это оно самое. Мне такой стиль не нравится, и сам я так не пишу.
Возможно, потому, что Рефал-6 позволяет не экономить на копированиях, и я
предпочитаю рекурсивный стиль. Но хочу высказаться в защиту этой формы,
которую использовал Турчин. Думаю, тут дело не в экономии копирований, а в
стиле мышления. Как ни странно, Турчин рассматривал работу рефал-программы
как пошаговый процесс с изменяющимся состоянием. Отсюда и понятие поля
зрения. Да, оно моделирует стек, неявно возникающий при рекурсии. Но при
мета-деятельности Турчин предпочитал поле зрения объектной программы
держать как бы целиком перед глазами. В центре - активная конкретизация, а
по краям - окружение. Отсюда и возник такой стиль. Он в каком-то смысле
сближает рефал с машиной Тьюринга, только вместо линейной ленты - дерево.
Когда-то около 90 года я попытался с ним на эту тему заговорить, как бы
предлагая перейти на рекурсивный стиль, но он как-то это сходу отверг, мол
так ему удобнее. Разговора по существу не получилось. Поэтому сейчас я его
так и понимаю, как написал выше.

С уважением,
Аркадий

пн, 14 дек. 2020 г. в 16:08, Александр Коновалов a.v.konovalov87_AT_mail.ru
<refal@botik.ru>:

> Василий, не надо пошаговую прокрутку. Я неправильно посчитал скобки.
> Во входной строке их не 4, а 3, поэтому всё сходится: 3+1=4.
>
>
>
> *From:* Василий Стеллецкий swi_AT_cnshb.ru <refal@botik.ru>
> *Sent:* Monday, December 14, 2020 4:58 PM
> *To:* refal@botik.ru
> *Subject:* Re: Запахи кода и антипаттерны в Рефале
>
>
>
> Александр.
> Действительно.
> Еще раз, Большое спасибо.
> PS Если хотите, могу прислать пошаговую прокрутку обоих вариантов...
>
>
>
> --
> С уважением,
>
> --
>
> Василий Стеллецкий
>
> mailto:s...@cnshb.ru <sw...@narod.ru>  mailto:sw...@narod.ru
> <sw...@narod.ru>
>
>
>
>
>
>
>
> 14.12.2020, 16:38, "Александр Коновалов a.v.konovalov87_AT_mail.ru" <
> refal@botik.ru>:
>
> Василий!
>
> Разница тут принципиальная. В первом варианте стек был системный,
> программист писал рекурсивную функцию, явно со стеком не манипулировал.
> Поскольку программист за стек не отвечает, сломаться стек не может.
> Во втором случае — стеком явно управляет программист. И он может ошибиться,
> например, положить состояние на один стек и не положить на другой. Или
> снять состояние только с одного стека. В любом случае стеки
> рассинхронизируются. Или допустить ошибку в формате, перепутав стек
> с обрабатываемыми данными (например, перепутав tL и tR).
>
> a =/0/k/Enum/ 'abc' (('de') 'f' ('gh') 'ij') 'k'.
> Enum e1 = k/EndEnum/k/DoEnum/e1 /1/..
> DoEnum s1 e2 sN = sN k/DoEnum/ e2 k/P1/sN..
>       (e1)e2 sN = k/DoEnum-Wrap/ *(k/DoEnum/ e1 sN.) e2*.
>       sN = sN
> DoEnum-Wrap *(e1 sN) e2* = (e1) k/DoEnum/ e2 sN.
> EndEnum e1 sN = e1
>
> И нету оборачивания скобки в рекурсивном решении.
>
> Один шаг сэкономился на EndEnum, т.к. в последнем предложении мы и стеки
> отбрасываем, и счётчик. Ещё шаги экономятся на обработке скобок.
> Открывающая скобка в обоих вариантах требует одного шага. Закрывающая
> скобка — двух шагов: последнее предложение DoEnum, где она видит аргумент
> с пустой строкой и счётчиком и DoEnum-Wrap, которая выбрасывает вон
> скобку и продолжает цикл DoEnum. Но закрывающих скобок 4, должно
> сэкономиться 4 шага. И один на EndEnum. 4+1≠4, где-то что-то я не учёл.
>
>
>
> С уважением,
> Александр Коновалов
>
>
>
> *From:* Василий Стеллецкий swi_AT_cnshb.ru <refal@botik.ru>
> *Sent:* Monday, December 14, 2020 4:05 PM
> *To:* refal@botik.ru
> *Subject:* Re: Запахи кода и антипаттерны в Рефале
>
>
>
> Александр!
> Большое спасибо за подробный рассказ!
> Но, то что в примере применили Вы - тоже самое: Справа стек.
> Только просмотренную часть Вы не собирали в левой скобке, а сразу выводили
> за пределы функции...
> Точнее стек получался из вызовов DoEnum-Wrap и скобок наизнанку ...
> Еще раз, Большое спасибо!
> P.S. А в этом варианте получился 31 шаг.
> 4 шага где-то сэкономили ;)
>
>
>
> --
> С уважением,
>
> --
>
> Василий Стеллецкий
>
> mailto:s...@cnshb.ru <sw...@narod.ru>  mailto:sw...@narod.ru
> <sw...@narod.ru>
>
>
>
>
>
>
>
> 14.12.2020, 15:23, "Александр Коновалов a.v.konovalov87_AT_mail.ru" <
> refal@botik.ru>:
>
> Василий!
>
> Выворачивание скобок, оно же сквозной просмотр, — это другое. Это
> использование стека для представления незакрытых скобок. Например, так:
>
> Enum e1 = k/DoEnum/ /0/ ('$') e1 '$'.
>
> * Формат: k/DoEnum/ sN (tL eS) eU tR
> *   eS — просканированная часть
> *   eU — непросканированная часть
> *   tL — стек просканированных частей слева
> *   tR — стек непросканированных частей справа
>
> * символ просто переносим
> DoEnum sN (tL eS) s1 eU tR = k/DoEnum/ k/P1/sN. (tL eS sN) eU tR.
> * в скобочный терм спускаемся
>        sN (tL eS) (e1) eU tR = k/DoEnum/ sN ((tL eS)) e1 (eU tR).
> * термы кончились, но стек не пустой
>        sN ((tL eS) e1) (eU tR) = k/DoEnum/ sN (tL eS (e1)) eU tR.
> * термы кончились и стек тоже пустой — выход из цикла
>        sN ('$' eS) '$' = eS
>
> Почему здесь скобки наизнанку? Потому что для частично просмотренного
> выражения вида
>
> e1 *(*e2 *(*e3 *^* e4*)* e5*)* e6
>
> где знак ^ означает позицию, вызов функции DoEnum будет иметь вид
>
> k/DoEnum/ ((('$' e1*)* e2*)* e3*)* e4 *(*e5 *(*e6 '$')).
>
> Т.е. незакрытые скобки перед ^ оказываются закрывающими, а неоткрытые
> после ^ — открывающими. А скобка между e3 и e4 служит указателем ^.
>
> У Турчина в учебнике по Рефалу-5 предлагается немного другой способ
> кодирования стека, но он не менее страшный, чем этот. Сам Турчин, похоже,
> осознавал неестественность такого программирования, поэтому в комплекте
> с Рефалом-5 поставляется препроцессор для сквозного просмотра скобок.
>
> Как по мне, лучше использовать рекурсию для обхода рекурсивных структур,
> чем наворачивать такие стеки.
>
>
>
> С уважением,
> Александр Коновалов
>
>
>
> *From:* Василий Стеллецкий swi_AT_cnshb.ru <refal@botik.ru>
> *Sent:* Monday, December 14, 2020 1:52 PM
> *To:* refal@botik.ru
> *Subject:* Re: Запахи кода и антипаттерны в Рефале
>
>
>
> Добрый день, Александр!
> Да, шагов поменьше!
>
> a =/0/k/Enum/ 'abc' (('de') 'f' ('gh') 'ij') 'k'.
>
> Enum e1 = *k/EndEnum/*k/DoEnum/e1 /1/.*.*
>
> DoEnum s1 e2 sN = sN k/DoEnum/ e2 k/P1/sN..
>
>       (e1)e2 sN = k/DoEnum-Wrap/ k/DoEnum/ e1 sN. (e2).
>
>    *   sN = sN*
>
> DoEnum-Wrap e1 sN (e2) = (e1) k/DoEnum/ e2 sN.
>
> *EndEnum e1 sN = e1*
>
>
>
> S:35 cc=0 M=1024
>
> ПЗ: /0/ /1/ /2/ /3/ ( ( /4/ /5/ ) /6/ ( /7/ /8/ ) /9/ /10/ ) /11/
>
> КОП:
>
>
>
> Спасибо, понял что такое "выворачивание скобок" :)
>
>
>
> --
> С уважением,
>
> --
>
> Василий Стеллецкий
>
> mailto:s...@cnshb.ru <sw...@narod.ru>  mailto:sw...@narod.ru
> <sw...@narod.ru>
>
>
>
>
>
>
>
> 14.12.2020, 13:25, "Александр Коновалов a.v.konovalov87_AT_mail.ru" <
> refal@botik.ru>:
>
> Добрый день, Василий!
>
> А если мы пишем для многопоточного Рефала, то статический ящик или копилка
> не подойдёт. Нужно использовать или динамический ящик, или передавать номер
> через параметр. Получится как-то так:
>
> Enum e1 = k/DoEnum/e1 /0/.
>
> DoEnum s1 e2 sN = sN k/DoEnum/ e2 k/P1/sN..
>       (e1)e2 sN = k/DoEnum-Wrap/ k/DoEnum/ e1 sN. (e2).
>
> DoEnum-Wrap e1 sN (e2) = (e1) k/DoEnum/ e2 sN.
>
> Если что, я не запускал этот код, могут быть опечатки. Также это решение
> эффективнее по числу шагов, чем вариант с копилкой.
>
>
>
> С уважением,
> Александр Коновалов
>
>
>
> *From:* Василий Стеллецкий swi_AT_cnshb.ru <refal@botik.ru>
> *Sent:* Monday, December 14, 2020 12:47 PM
> *To:* refal@botik.ru
> *Subject:* Re: Запахи кода и антипаттерны в Рефале
>
>
>
> Добрый день всем!
>
> Я про задачку...
> Ну, на мой взгляд не просто для понимания...
> На других диалектах Рефала - да пожалуйста!
> В этой задаче удобно использовать Ящики или Копилку.
> Например с копилкой:
>
> a =/0/k/Enum/ 'abc' (('de') 'f' ('gh') 'ij') 'k'.
>
> Enum s1e2=k/Enum1/k/ВК/'n'..k/Enum/e2.
>
>      (e1)e2=(k/Enum/e1.)k/Enum/e2.
>
>      =
>
> Enum1 =/1/k/ЗК/'n='/2/.
>
>       sn=snk/ЗК/'n='k/P1/sn..
>
> Результат:
>
> S:62 cc=0 M=1024
>
> ПЗ: /0/ /1/ /2/ /3/ ( ( /4/ /5/ ) /6/ ( /7/ /8/ ) /9/ /10/ ) /11/
>
> КОП: ( 'n' '=' /12/ )
>
> (первый /0/ в поле зрения не имеет отношения к задаче, это мой интерфейс)
>
>
>
>
>
>
> --
> С уважением,
>
> --
>
> Василий Стеллецкий
>
> mailto:s...@cnshb.ru <sw...@narod.ru>  mailto:sw...@narod.ru
> <sw...@narod.ru>
>
>
>
>
>
>
>
> 14.12.2020, 10:47, "Александр Коновалов a.v.konovalov87_AT_mail.ru" <
> refal@botik.ru>:
>
> Доброе утро всем!
>
>
>  1. Выворачивание скобок наизнанку, для организации прохода по выражению.
>
>
> К представлению объектных выражений этот приём (антиприём) не имеет
> отношение. Он, скорее, характерен для базисного Рефала (Рефала-2), в
> котором нет ничего подобного let-конструкциям (условия, перестройки,
> действия). И благодаря этому сквозному обходу исчезает нужда во
> вспомогательных функциях, можно обойтись одной.
>
> Но, вообще этот приём уродлив, хоть и пропагандировался Турчиным.
>
>
>
>  2. Боязнь копирования кусков выражений в разные «дочерние» функции.
>
>
> А в Рефале-5 ещё и в условия.
>
> У меня в Рефале-5λ копирование выражений дорогое, но я копировать их по
> умолчанию не боюсь. Потому что потом я нахожу узкие места, изучая профиль
> программы, и устраняю лишние копирования уже в них.
>
> А нет ли в Рефале Плюс другой боязни — боязни конкатенации?
>
>
> Задача. Заменить в выражении все символы последовательными натуральными
> числами:
>
> <Enum 'abc' (('de') 'f' ('gh') 'ij') 'k'> → 1 2 3 ((4 5) 6 (7 8) 9 10) 11
>
> Решение на Рефале-5λ, эффективное (O(n)) и простое для понимания (на мой
> взгляд):
>
> Enum {
>   e.Expr
>     = <DoEnum e.Expr 1> : e.Expr^ s.Num
>     = e.Expr;
> }
>
> DoEnum {
>   /* пусто */ s.Num = s.Num;
>
>   s.X e.Expr s.Num = s.Num <DoEnum e.Expr <+1 s.Num>>;
>
>   (e.Nested) e.Expr s.Num
>     = <DoEnum e.Nested s.Num> : e.Nested^ s.Num^
>     = (e.Nested) <DoEnum e.Expr s.Num>;
> }
>
> Конструкции = … : … в Enum и в последнем предложении DoEnum неявно
> транслируются в вызов вспомогательной функции. Знак ^ после имени
> переменной в образце означает, что она не повторная. Представление данных —
> плоское списковое, то самое с дорогим копированием и копеечной
> конкатенацией.
>
> Как будет выглядеть O(n) решение в других диалектах Рефала?
>
>
> С уважением,
> Александр Коновалов
>
>
>
> -----Original Message-----
> From: Sergei M. Abramov abram_AT_botik.ru <refal@botik.ru>
> Sent: Monday, December 14, 2020 4:27 AM
> To: Александр Коновалов a.v.konovalov87_AT_mail.ru <refal@botik.ru>
> Subject: Re: Запахи кода и антипаттерны в Рефале
>
> День добрый, всем!
>
>
>  А какие вы можете назвать запахи кода и антипаттерны, характерные для
>  Рефала?
>
>
> Все, что вскрывает (или скрывает?) недостатки используемого представления
> объектных выражений и приводит к чудовищному (для
> пониманию) кода:
>
> 1. Выворачивание скобок наизнанку, для организации прохода по выражению.
>
> 2. Боязнь копирования кусков выражений в разные "дочерние" функции.
>
> Этим страдают многия языки. Например, в Эрланге целый культ на тему
> "стремись к хвостовой рекурсии!" и "пиши с аккумулятором, а потом выдай
> результат, навесив на него reverse (Который, видимо, у них написан на не
> Erlang-е)".
>
> Если мы стремимся к самодокументированному коду без комментариев, то такие
> фенечки должны не приветствоваться.
>
> С уважением,
>
> Абрамов С.М.
> ab...@botik.ru
> мобильный: +7(903)2928308
>
>
>

-- 
_______________
*С уважением, *
*Аркадий Климов,*
*с.н.с. ИППМ РАН,*
*+7(499)135-32-95*
*+7(916)072-81-48*
  • Re:... Andrei Klimov andrei_AT_klimov . net
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
  • Re:... Василий Стеллецкий swi_AT_cnshb . ru
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
      • ... Василий Стеллецкий swi_AT_cnshb . ru
        • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Василий Стеллецкий swi_AT_cnshb . ru
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Василий Стеллецкий swi_AT_cnshb . ru
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Arkady Klimov arkady . klimov_AT_gmail . com
          • ... nikolai . kondratiev_AT_gmail . com
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru

Ответить