In functional programming since almost all data structure are immutable, when the state has to change a new structure is created. Does this mean a lot more memory usage?
Dipende dalla struttura dei dati, dalle esatte modifiche eseguite e, in alcuni casi, dall'ottimizzatore. Come esempio, consideriamo prepending in un elenco:
list2 = prepend(42, list1) // list2 is now a list that contains 42 followed
// by the elements of list1. list1 is unchanged
Qui il requisito di memoria aggiuntiva è costante, così come il costo di esecuzione di chiamare prepend
. Perché? Poiché prepend
crea semplicemente una nuova cella che ha 42
come testata e list1
come coda. Non è necessario copiare o altrimenti iterare su list2
per ottenere ciò. Cioè, ad eccezione della memoria richiesta per memorizzare 42
, list2
riutilizza la stessa memoria utilizzata da list1
. Poiché entrambe le liste sono immutabili, questa condivisione è perfettamente sicura.
Analogamente, quando si lavora con strutture ad albero bilanciate, la maggior parte delle operazioni richiede solo una quantità logaritmica di spazio aggiuntivo perché tutto, ma un percorso dell'albero può essere condiviso.
Per gli array la situazione è leggermente diversa. Ecco perché, in molti linguaggi FP, gli array non sono comunemente usati. Tuttavia, se fai qualcosa come arr2 = map(f, arr1)
e arr1
non viene mai più utilizzato dopo questa riga, un ottimizzatore intelligente può effettivamente creare codice che muta arr1
invece di creare un nuovo array (senza influire sul comportamento del programma). In tal caso, la performance sarà come in una lingua imperativa, naturalmente.