Я не знаю правильной терминологии для того, чтобы задать этот вопрос, поэтому вместо этого я опишу его множеством слов, потерпите меня.
Фон , просто так, что мы находимся на одной странице: программы часто содержат кэши - компромисс между временем и памятью. Распространенная ошибка программиста - забыть обновить кэшированное значение после изменения одного из его исходных источников / прецедентов. Но парадигма потока данных или FRP не застрахована от таких ошибок. Если у нас есть несколько чистых функций, и мы соединяем их вместе в ориентированном графе зависимостей, то узлы могут кэшировать свое выходное значение и использовать его повторно, пока не изменится какой-либо из входов функции. Эта системная архитектура описана в статье Кэширование в средах на основе потоков данных, и на императивном языке она более или менее аналогична запоминанию.
Проблема : Когда один из входных данных функции изменяется, нам все равно приходится выполнять функцию целиком, отбрасывая ее кэшированные выходные данные и пересчитывая заново. Во многих случаях это кажется мне расточительным. Рассмотрим простой пример, который генерирует список «5 лучших». Входные данные представляют собой несортированный список чего угодно. Он передается в качестве входных данных в функцию, которая выводит отсортированный список. Который, в свою очередь, является входом для функции, которая принимает только первые 5 элементов. В псевдокоде:
input = [5, 20, 7, 2, 4, 9, 6, 13, 1, 45]
intermediate = sort(input)
final_output = substring(intermediate, 0, 5)
Сложность функции сортировки составляет O (N log N). Но учтите, что этот поток используется в приложении, в котором входные данные изменяются лишь незначительно, добавляя 1 элемент. Вместо того, чтобы каждый раз заново сортировать с нуля, на самом деле было бы быстрее, фактически O (N), использовать функцию, которая обновляет старый кэшированный отсортированный список, вставляя новый элемент в правильную позицию. Это только один пример - многие функции «с нуля» имеют такие «инкрементные обновления». Кроме того, возможно, новый элемент даже не появится в final_output, потому что он находится после 5-й позиции.
Моя интуиция предполагает, что можно было бы каким-то образом добавить такие функции «инкрементного обновления» в систему потока данных, бок о бок с существующими функциями «с нуля». Конечно, перерасчет всего с нуля всегда должен давать тот же результат, что и набор дополнительных обновлений. Система должна обладать свойством, что если каждая из отдельных примитивных пар FromScratch-Incremental всегда дает один и тот же результат, то большие составные функции, построенные из них, также должны автоматически давать тот же результат.
Вопрос : возможно ли иметь систему / архитектуру / парадигму / мета-алгоритм, которая может поддерживать как функции FromScratch, так и их инкрементные аналоги, сотрудничая для повышения эффективности и объединяясь в большие потоки? Если нет, то почему? Если кто-то уже исследовал эту парадигму и опубликовал ее, как она называется, и могу ли я получить краткое описание того, как она работает?