В текущей реализации прогонки аргументы встраиваемых и прогоняемых функций могут быть только пассивными:
|
/* Попытка оптимизации, только если вызов пассивный */ |
|
, <IsPassiveCall e.Args>: True |
|
= <Solve |
|
/* Попытка оптимизации, только если вызов пассивный */ |
|
, <IsPassiveCall e.Args>: True |
|
= <Solve |
Это было намеренным ограничением на ВКР @InfiniteDisorder‘а, поскольку содержательной частью работы был алгоритм обобщённого сопоставления и собственно прогонка.
Однако, можно прогонять и вызовы, аргументы которых содержат другие вызовы. Причём это описано даже в классических статьях Турчина (Турчин, 1972 и Турчин, 1974). Вызовы функций заменяются новыми e-переменными (т.н. «неразменными» переменными), которые запрещено сужать. Если решение уравнения содержит сужение «неразменной» переменной — то этот вызов просто оптимизировать нельзя.
Тонкость здесь в том, что вызовы функций могут иметь побочный эффект, а при встраивании-прогонке они могут переупорядочиться (включая дублирование и удаление). Соответственно, также нужно будет контролировать, что прогонка не меняет относительный порядок вызовов.
В текущей реализации прогонки аргументы встраиваемых и прогоняемых функций могут быть только пассивными:
refal-5-lambda/src/compiler/OptTree-Drive.ref
Lines 284 to 286 in 4ed95a0
refal-5-lambda/src/compiler/OptTree-Drive.ref
Lines 364 to 366 in 4ed95a0
Это было намеренным ограничением на ВКР @InfiniteDisorder‘а, поскольку содержательной частью работы был алгоритм обобщённого сопоставления и собственно прогонка.
Однако, можно прогонять и вызовы, аргументы которых содержат другие вызовы. Причём это описано даже в классических статьях Турчина (Турчин, 1972 и Турчин, 1974). Вызовы функций заменяются новыми e-переменными (т.н. «неразменными» переменными), которые запрещено сужать. Если решение уравнения содержит сужение «неразменной» переменной — то этот вызов просто оптимизировать нельзя.
Тонкость здесь в том, что вызовы функций могут иметь побочный эффект, а при встраивании-прогонке они могут переупорядочиться (включая дублирование и удаление). Соответственно, также нужно будет контролировать, что прогонка не меняет относительный порядок вызовов.