Non conosco la terminologia corretta per porre questa domanda, quindi la descriverò con molte parole, abbiate pazienza.
Sfondo , solo così siamo sulla stessa pagina: i programmi spesso contengono cache - un compromesso tempo / memoria. L'errore di un programmatore comune è dimenticare di aggiornare un valore memorizzato nella cache dopo aver modificato una delle sue origini / precedenti a monte. Ma il flusso di dati o il paradigma di programmazione FRP è immune da tali errori. Se abbiamo un numero di funzioni pure e le colleghiamo insieme in un grafico di dipendenza diretto, i nodi possono avere il loro valore di output memorizzato nella cache e riutilizzato fino a quando uno qualsiasi degli input della funzione cambia. Questa architettura di sistema è descritta nel documento Caching In Dataflow-based Environments e in un linguaggio imperativo è più o meno analogo alla memoizzazione.
Problema : quando uno degli input di una funzione cambia, dobbiamo ancora eseguire la funzione nel suo insieme, eliminando l'output memorizzato nella cache e ricalcolando da zero. In molti casi, questo mi sembra dispendioso. Considera un semplice esempio che genera un elenco dei "primi 5 qualunque". I dati di input sono un elenco non ordinato di qualunque cosa. Viene passato come input a una funzione che genera un elenco ordinato. Che a sua volta viene inserito in una funzione che accetta solo i primi 5 elementi. In pseudocodice:
input = [5, 20, 7, 2, 4, 9, 6, 13, 1, 45]
intermediate = sort(input)
final_output = substring(intermediate, 0, 5)
La complessità della funzione di ordinamento è O (N log N). Ma considera che questo flusso viene utilizzato in un'applicazione in cui l'input cambia solo un po 'alla volta, aggiungendo 1 elemento. Invece di riordinare ogni volta da zero, sarebbe più veloce, infatti O (N), utilizzare una funzione che aggiorna il vecchio elenco ordinato memorizzato nella cache inserendo il nuovo elemento nella posizione corretta. Questo è solo un esempio: molte funzioni "da zero" hanno simili controparti di "aggiornamento incrementale". Inoltre, forse l'elemento appena aggiunto non apparirà nemmeno in final_output perché è dopo la 5a posizione.
La mia intuizione suggerisce che potrebbe essere possibile in qualche modo aggiungere tali funzioni di "aggiornamento incrementale" a un sistema di flusso di dati, fianco a fianco con le esistenti funzioni "da zero". Naturalmente, il ricalcolo di tutto da zero deve sempre dare lo stesso risultato di una serie di aggiornamenti incrementali. Il sistema dovrebbe avere la proprietà che se ciascuna delle singole coppie FromScratch-incrementale primitive sempre danno lo stesso risultato, quindi le funzioni composte grandi costruite da loro dovrebbero dare automaticamente lo stesso risultato.
Domanda : è possibile avere un sistema / architettura / paradigma / meta-algoritmo in grado di supportare sia le funzioni FromScratch che le loro controparti incrementali, cooperando per l'efficienza e composto in grandi flussi? Se no, perché? Se qualcuno ha già studiato questo paradigma e lo ha pubblicato, come si chiama, e posso ottenere un breve riassunto di come funziona?