Добрый день всем!

Публикую слайды прошедшего семинара:

https://mazdaywik.github.io/direct-link/2021-05-17-Konovalov-Closures-and-Optimizations-Refal-5-lambda.pdf

Краткое содержание: я рассказал про Рефал-5λ, про оптимизации, реализованные в 
нём, привёл примеры того, что оптимизации реализуют неэквивалентные 
преобразования программ, рассмотрел два способа решения этой проблемы.

Доклад не только занял весь семинар, но и растянул семинар примерно на три 
часа. Поэтому обсудить, какой из двух рассмотренных способов лучше, мы не 
успели.

 

Проблема связана с тем, что замыкания — ссылочные данные, а оптимизации 
(прогонка и специализация, включая специализацию замыканий) умеют работать 
только с данными-значениями. Более того, промежуточный язык, в котором 
выполняются преобразования, не отражает того факта, что замыкания — ссылочные 
данные. В неоптимизированной программе это сходит с рук, а в оптимизированной 
возможны проблемы (в презентации приведены 4 разных примера).

Было предложено два пути решения:

*       расширить промежуточный язык поддержкой ссылочных типов, 
соответственно, усложнить оптимизации и генерацию кода,
*       отказаться от ссылочных типов вовсе, сделав замыкания типами-значениями 
— равенство будет проверяться не по ссылке, а по содержимому.

Оба варианта имеют свои преимущества и недостатки, ни один из них существенно 
не превосходит другой. Поэтому, как исправить проблему, я не знаю. В разные 
моменты времени я склоняюсь то к одному, то к другому решению.

 

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

 

From: Andrei Klimov andrei_AT_klimov.net <refal@botik.ru> 
Sent: Sunday, May 16, 2021 11:06 PM
To: refal@botik.ru
Subject: Рефал-семинар 17 мая 2021 в 10:30 в Zoom'e

 

Добрый вечер!

В понедельник 17 мая 2020 в 10:30 часов соберемся на онлайн-семинар по Рефалу:

*  Александр Коновалов (МГТУ имени Н.Э. Баумана)
Проблемы ссылочной эквивалентности замыканий при эквивалентных преобразованиях 
программ в Рефале-5λ

Zoom-сеанс:

 

 <https://us02web.zoom.us/j/86888134690?pwd=ZTlnUWQvSUVPN3RVUk1UdU8rZjB6Zz09> 
https://us02web.zoom.us/j/86888134690?pwd=ZTlnUWQvSUVPN3RVUk1UdU8rZjB6Zz09

Meeting ID: 868 8813 4690
Passcode: Yaq97A 

Аннотация:


Диалект Рефал-5λ является расширением Рефала-5 безымянными функциями. Внутри 
безымянных функций можно ссылаться на переменные, связанные вне её. Для 
безымянной функции во время выполнения программы создается объект замыкания, 
содержащий указатель на код данной функции и значения захваченных переменных. 
Эти объекты с точки зрения языка являются символами (сопоставляются с 
s-переменными) и сравниваются на равенство по ссылке.

Пример программы с замыканиями:

 

Map {
  s.Func t.Next e.Rest = <s.Func t.Next> <Map s.Func e.Rest>;
  s.Func /* пусто */  = /* пусто */;
}

$ENTRY CartProd {
  (e.Xs) (e.Ys)
    = <Map { t.X = <Map { t.Y = (t.X t.Y) } e.Ys> } e.Xs>
}

Переменные, захваченные замыканиями, подчеркнуты.

Компилятор Рефала-5λ поддерживает две оптимизации: специализации и прогонки 
функций. Оптимизация специализации для специально помеченных функций создает 
специализированные экземпляры функций, учитывающие информацию о вызове, 
известную во время компиляции. В частности, для обоих вызовов Map в функции 
CartProd будут строиться экземпляры, учитывающие тот факт, что аргументами 
являются конкретные замыкания:

 

$ENTRY CartProd {
  (e.Xs) (e.Ys) = <Map <mailto:Map@1%20(e.Ys) e.Xs> @1 (e.Ys) e.Xs>;
}

Map@1 {
 (e.Ys) t.Next e.Rest = <{ t.X = <Map <mailto:Map@2 t.X e.Ys> @2 t.X e.Ys> } 
t.Next> <Map <mailto:Map@1%20(e.Ys) e.Rest> @1 (e.Ys) e.Rest>;
  (e.Ys) /* пусто */ = /* пусто */;
}

Map@2 {
  t.X t.Next e.Rest = <{ t.Y = (t.X t.Y) } t.Next> <Map <mailto:Map@2 t.X 
e.Rest> @2 t.X e.Rest>;
  t.X /* пусто */ = /* пусто */;
}

Оптимизация прогонки встраивает функции в точки их вызова. Это преобразование 
программ было описано Турчиным (для подмножества Рефала) в 1972 (тезисы 
конференции Киев-Алушта) и в 1974 (сборник ЦНИПИАС) годах. В рассмотренном 
примере оптимизация прогонки встроит вызовы вложенных функций:

 

$ENTRY CartProd {
  (e.Xs) (e.Ys) = <Map <mailto:Map@1%20(e.Ys) e.Xs> @1 (e.Ys) e.Xs>;
}

Map@1 {
 (e.Ys) t.Next e.Rest = <Map <mailto:Map@2 t.Next e.Ys> @2 t.Next e.Ys> <Map 
<mailto:Map@1%20(e.Ys) e.Rest> @1 (e.Ys) e.Rest>;
  (e.Ys) /* пусто */ = /* пусто */;
}

Map@2 {
  t.X t.Next e.Rest = (t.X t.Next) <Map <mailto:Map@2 t.X e.Rest> @2 t.X 
e.Rest>;
  t.X /* пусто */ = /* пусто */;
}

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

На семинаре мы рассмотрим примеры нарушения эквивалентности преобразований и 
рассмотрим пути решения этой проблемы. Сразу скажу, что каждый из предлагаемых 
мною вариантов имеет свои недостатки. Надеюсь, на семинаре мы сможем найти 
приемлемый способ решения этой проблемы.

 

До Zoom-встречи!

 

Андрей Климов

  • Реф... Andrei Klimov andrei_AT_klimov . net
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
      • ... Александр Гусев gusev_aleksandr_AT_mail . ru
        • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Александр Гусев gusev_aleksandr_AT_mail . ru
            • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
              • ... Александр Гусев gusev_aleksandr_AT_mail . ru

Ответить