Добрый вечер, Александр!

«Читая как-то информацию о Рефале в сети, наткнулся на упоминание отсутствия 
вложенных функций как недостатка языка.»

Интересно понять, что конкретно имелось ввиду, потому что «вложенная функция» — 
понятие растяжимое. В языках программирования, где вложенные функции есть (как 
функции высших порядков в функциональных языках или как вложенные процедуры в 
классическом Паскале), они характеризуются следующими свойствами: синтаксически 
они расположены внутри определения другой функции, область видимости ограничена 
той функцией, где они определены, и вложенные функции могут видеть локальные 
переменные окружающей функции.

Вариант с клозами реализует только первые два свойства. Классический Рефал-5 
содержит блоки — конструкции вида

, Res
: {
    Sent;
    Sent;
    Sent;
  }

Их вполне можно считать вложенными функциями, хоть они и вызываются только один 
раз. Они действительно синтаксически находятся внутри другой функции, 
недоступны извне и, главное, в них доступны связанные снаружи переменные.

Max {
  s.X s.Y
    , <Sub s.X s.Y>
    : {
        '−' s.d = s.Y;
        s.d = s.X;
      };
}

Вложенные функции как функции высших порядков предложены Сергеем Скоробогатовым 
в Рефале-7:

Скоробогатов С. Ю., Чеповский А. М. Разработка нового диалекта языка Refal // 
Информационные технологии. 2006. 9. C. 31-38.
https://bmstu-iu9.github.io/Skorobogatov-Refal-7.pdf

Ограниченная поддержка вложенных функций высшего порядка есть в Рефале-5λ — 
доступны только безымянные вложенные функции.


«Под клозом понимается группа строк паттерна, начинающаяся с одного и того же 
символа, предпочтительно идентификатора. При вызове функции с указанием 
конкретного идентификатора, набор обрабатываемых паттернов сократится до строк, 
начинающихся с этого идентификатора.»

На самом деле всё наоборот. Если почитать первый препринт Турчина о Рефале:

Программирование на языке рефал. I. Неформальное введение в программирование на 
языке рефал. (keldysh.ru)

то можно узнать следующее. Изначально, программа на Рефале была просто набором 
предложений, а функциональные скобки (скобки конкретизации) были «безымянными». 
Левая обозначалась к, правая — . (точка). (Знаки < и > Турчин стал использовать 
уже в Америке, там их ему на конференции предложил МакКарти.)

Уже после определения скобок конкретизации на странице 35 препринта (по ссылке 
выше) Турчин вводит понятие детерминатива — символ после левой скобки 
конкретизации. А группу предложений с общим детерминативом — как функцию. 
Вообще, на сколько я понимаю, детерминативы введены отчасти ради эффективной 
реализации. В этом случае при вычислении конкретизации будут просматриваться не 
все предложения программы, а только несколько.

Вводить кавер-функцию с несколькими подфункциями-клозами можно, такой стиль 
программирования на Рефале существует. Правда, иногда отдельные клозы не 
именуют, а просто пользуются различными непересекающимися (или что хуже, 
пересекающимися) форматами. Такой стиль опасен тем, что ошибившись при вызове, 
можно случайно вызвать не ту «подфункцию» функции.


«„Авторекурсия“ — это вызов функцией самой себя, синтаксически выделяемой как 
„<<“ вместо „<имя_функции“. Никаких других „вольностей“ в синтаксисе тут нет.»

На мой вкус, знак «<< …>» неудачный. Глаз привыкает, что знаки < и > являются 
парными скобками и всегда должны быть сбалансированы, их число должно быть 
одинаково. Я бы предпочёл какой-нибудь другой, выделяющийся знак для этой цели, 
например «<@ …>». Сам я когда-то подумывал о слове $REC для аналогичной цели, 
но сначала поленился, а потом забил — будет потерян один удобный приём отладки 
(см. здесь пример отладки DoFib).


С уважением,
Александр Коновалов



From: Александр Гусевgusev_aleksandr_AT_mail.ru 
Sent: Thursday, March 11, 2021 1:52 PM
To: refal@botik.ru 
Subject: Изобретение велосипеда

Добрый день, коллеги!

Поделюсь мыслью, показавшейся мне интересной.

Читая как-то информацию о Рефале в сети, наткнулся на упоминание отсутствия 
вложенных функций как недостатка языка. По ходу реализации оказалось, что это 
не вполне соответствует действительности и такой механизм есть, хотя он не 
вполне явный и требует некоторой доработки.
Я добавлю здесь небольшой текст из своего описания. Возможно, это будет 
интересно ещё кому-то.

Позволил себе поупражняться в изобретении наименований, если что-то уже было 
сделано на этот счёт до меня, но я не знаю об этом.
«Авторекурсия» — это вызов функцией самой себя, синтаксически выделяемой как 
«<<» вместо «<имя_функции». Никаких других «вольностей» в синтаксисе тут нет.

Отрывок:
При комбинации авторекурсии и идентификаторов добавляется удобное качество: 
локальные подфункции внутри одной функции, именуемые клозами.

Под клозом понимается группа строк паттерна, начинающаяся с одного и того же 
символа, предпочтительно идентификатора. При вызове функции с указанием 
конкретного идентификатора, набор обрабатываемых паттернов сократится до строк, 
начинающихся с этого идентификатора. Если каждый паттерн начинается с 
идентификатора, то функция будет натуральной кавер — функцией (НКФ, natural 
cover) с гарантированной ясной логикой использования клозов.


Пример печати квадратов цепочки макроцифр:

Cover {

        Square s.1 = <Mul s.1 s.1>;

        Line = <Prout 'Конец списка'>;

        Line e.1 = <Prout '=' e.1>;

        = <<Line>;

        s.1 = <<Line <<Square s.1>>;

        s.1 e.1 = << s.1> << e.1>;

};

То же, но в «классическом» варианте:

Square {

        s.1 = <Mul s.1 s.1>;

};

Line {

        = <Prout 'Конец списка'>;

        e.1 = <Prout '=' e.1>;

};

Cover {

        = <Line>;

        s.1 = <Line <Square s.1>>;

        s.1 e.1 = <Cover s.1> <Cover e.1>;

};

НКФ можно даже оптимизировать на уровне выполнения — сократить перебор 
вариантов без участия программиста на Рефале. Это вопрос на перспективу.

С уважением,
Александр Гусев
gusev_aleksa...@mail.ru
  • Реф... Александр Коновалов a . v . konovalov87_AT_mail . ru
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
      • ... Arkady Klimov arkady . klimov_AT_gmail . com
        • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Yuri Klimov yuri_AT_klimov . net
            • ... Sergei M. Abramov
              • ... Александр Гусев gusev_aleksandr_AT_mail . ru
                • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
                • ... Александр Гусев gusev_aleksandr_AT_mail . ru
                • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
                • ... Sergei M. Abramov
                • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
                • ... Andrei Klimov andrei_AT_klimov . net
                • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
                • ... Andrei Klimov andrei_AT_klimov . net

Ответить