TL; DR: i linguaggi funzionali gestiscono la ricorsione meglio di quelli non funzionali?
Attualmente sto leggendo il codice completo 2. Ad un certo punto del libro, l'autore ci mette in guardia sulla ricorsione. Dice che dovrebbe essere evitato quando possibile e che le funzioni che usano la ricorsione sono generalmente meno efficaci di una soluzione che usa i loop. Ad esempio, l'autore ha scritto una funzione Java usando la ricorsione per calcolare il fattoriale di un numero simile (potrebbe non essere esattamente lo stesso poiché al momento non ho il libro con me):
public int factorial(int x) {
if (x <= 0)
return 1;
else
return x * factorial(x - 1);
}
Questo è presentato come una cattiva soluzione. Tuttavia, nei linguaggi funzionali, l'uso della ricorsione è spesso il modo preferito di fare le cose. Ad esempio, ecco la funzione fattoriale in Haskell usando la ricorsione:
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
Ed è ampiamente accettata come una buona soluzione. Come ho visto, Haskell usa la ricorsione molto spesso e non ho visto da nessuna parte che è malvisto.
Quindi la mia domanda in sostanza è:
- I linguaggi funzionali gestiscono la ricorsione meglio di quelli non funzionali?
EDIT: sono consapevole che gli esempi che ho usato non sono i migliori per illustrare la mia domanda. Volevo solo sottolineare che Haskell (e i linguaggi funzionali in generale) usano la ricorsione molto più spesso dei linguaggi non funzionali.
factorial n = product [1..n]
è più conciso, più efficiente e non riempie troppo lo stack n
(e se hai bisogno di memoization, sono necessarie opzioni completamente diverse). product
è definito in termini di alcuni fold
, che è definito in modo ricorsivo, ma con estrema cura. La ricorsione è una soluzione accettabile per la maggior parte del tempo, ma è comunque facile farlo in modo errato / non ottimale.