No sé la terminología correcta para hacer esta pregunta, así que la describiré con muchas palabras, tengan paciencia conmigo.
Antecedentes , solo para estar en la misma página: los programas a menudo contienen cachés, una compensación de tiempo / memoria. El error de un programador común es olvidar actualizar un valor almacenado en caché después de cambiar una de sus fuentes / precedentes ascendentes. Pero el paradigma de programación de flujo de datos o FRP es inmune a tales errores. Si tenemos varias funciones puras, y las conectamos en un gráfico de dependencia dirigido, entonces los nodos pueden tener su valor de salida almacenado en caché y reutilizado hasta que cambie cualquiera de las entradas de la función. Esta arquitectura de sistema se describe en el documento Almacenamiento en caché en entornos basados en flujo de datos y en un lenguaje imperativo es más o menos análogo a la memorización.
Problema : cuando una de las entradas de una función cambia, todavía tenemos que ejecutar la función como un todo, desechar su salida en caché y volver a calcular desde cero. En muchos casos, esto me parece un desperdicio. Considere un ejemplo simple que genera una lista de "los 5 mejores". Los datos de entrada son una lista sin clasificar de lo que sea. Se pasa como entrada a una función que genera una lista ordenada. Lo que a su vez es entrada a una función que toma solo los primeros 5 elementos. En pseudocódigo:
input = [5, 20, 7, 2, 4, 9, 6, 13, 1, 45]
intermediate = sort(input)
final_output = substring(intermediate, 0, 5)
La complejidad de la función de clasificación es O (N log N). Pero considere que este flujo se usa en una aplicación donde la entrada solo cambia un poco a la vez, agregando 1 elemento. En lugar de volver a ordenar desde cero cada vez, sería más rápido, de hecho, O (N), usar una función que actualice la lista ordenada en caché anterior insertando el nuevo elemento en la posición correcta. Este es solo un ejemplo: muchas funciones "desde cero" tienen esas contrapartes de "actualización incremental". Además, tal vez el elemento recién agregado ni siquiera aparecerá en la salida final porque está después de la quinta posición.
Mi intuición sugiere que podría ser posible de alguna manera agregar tales funciones de "actualización incremental" a un sistema de flujo de datos, junto con las funciones existentes "desde cero". Por supuesto, volver a calcular todo desde cero siempre debe dar el mismo resultado que un montón de actualizaciones incrementales. El sistema debe tener la propiedad de que si cada uno de los pares FromScratch-Incremental primitivas individuales siempre dan el mismo resultado, a continuación, las funciones compuestas más grandes construidas a partir de ellos deben también dar automáticamente el mismo resultado.
Pregunta : ¿Es posible tener un sistema / arquitectura / paradigma / meta-algoritmo que pueda soportar tanto las funciones FromScratch como sus contrapartes incrementales, cooperando para la eficiencia y compuestas en grandes flujos? Si no, ¿por qué? Si alguien ya investigó este paradigma y lo publicó, ¿cómo se llama? ¿Puedo obtener un breve resumen de cómo funciona?