Кто думают что итераторы могут рефакторизировать только линейные циклы могут посмотреть на bac4th-итератор двоичного поиска fork-cycle и определённую через него процедуру reverse-function (
~profit/lib/binary-search.f), которая находит обратные функции от функций с одним аргументом:
Код:
: 10/ ( res -- x )
0 SWAP DUP \ задаём область поиска аргумента x, при котором f(x)=res
DROPB \ снимаем флаг прямого попадания по окончании работы reverse-function
reverse-function
10 * ; \ функция от которой берём обратную
Или можно искать квадратные корни так (слово factor -- из
~profit/lib/bin-mul.f):
Код:
: sqrt
DUP MAX{ factor DUP }MAX \ находим максимальную степень двойки в числе
2/ \ берём от неё квадратный корень, т.е. делим степень на два
defactor \ переводим из экспоненциального вида к обычному, т.е. возводим в степень
DUP 2* \ формируем диапазон в котором находится корень числа
ROT DROPB reverse-function DUP * ;
Или даже целочисленно делить:
Код:
: // ( a b -- a/b )
OVER -ROT ( a a b )
LOCAL b DUP b !
MAX{ factor DUP }MAX 1+
RSHIFT DUP 2*
ROT DROPB reverse-function b @ * ;
Хотя конечно, именно эти примеры сами по себе никакого практического смысла не имеют. Но в
~profit/prog/sort/sort.f может пригодится чтобы убрать хотя бы одну из трёх генерируемых функций (две -- для сортировки, одна -- для двоичного поиска).
Кроме того, fork-cycle демонстрирует и ещё одну особенность: управление ходом итератора (цикла) из подчинённого (внешнего) слова. Такой же принцип показан в
~profit/misc/variableStepIterating.f для линейных циклов по диапазону с переменным шагом.