Che cos’è una chiamata ricorsiva?

Nella programmazione, una chiamata ricorsiva è un comando all’interno di una subroutine o funzione che dice al programma di eseguire nuovamente la stessa subroutine. La ripetizione dell’esecuzione può essere il risultato diretto della funzione, oppure può essere attivata una seconda funzione che, a sua volta, fa riferimento alla prima funzione. Una chiamata ricorsiva ha alcune somiglianze con il temuto ciclo infinito, ma la subroutine ha sempre un’istruzione condizionale che dice al programma quando smettere di ripetere la ricorsione.

Il concetto di ricorsione è forse meglio illustrato attraverso l’uso di un esempio. Supponiamo che un roofer stia applicando nuove tegole a una casa. Per cominciare, deve portare un fascio di tegole sul tetto. Una volta che ha inchiodato il primo fascio, deve scendere la scala, recuperare un altro fascio e inchiodarlo al suo posto. Il processo continua come una serie di “vai, prendi, torna” fino a quando non viene applicata l’ultima tegola. A quel punto, il roofer è libero di passare al lavoro successivo o tornare a casa.

Sebbene l’esempio sia una semplificazione eccessiva, contiene tutti gli elementi di una chiamata ricorsiva. C’è un punto di partenza, il roofer deve recuperare ciò di cui ha bisogno, tornare all’inizio e, quando la condizione finale è soddisfatta, fermarsi. Questo è fondamentalmente ciò che fa il programma; inizia, implementa un’azione, ritorna a se stesso e termina quando si verifica la condizione finale.

La condizione finale è detta caso base. È essenziale per tutte le chiamate ricorsive; senza di essa, la funzione continuerebbe a ripetersi. Nella migliore delle ipotesi, ciò si traduce nel prosciugare le risorse di memoria del sistema. Normalmente il sovraccarico farà crashare il programma ad un certo punto, ma nel momento in cui il problema viene scoperto, possono essere causati danni significativi.

I programmatori esperti potrebbero riconoscere la somiglianza tra una chiamata ricorsiva e un ciclo “for” o “while”. Se, ad esempio, l’obiettivo è trovare il conteggio totale dell’inventario di tutte le scorte con numeri di parte maggiori di 999, un ciclo “for” indica al programma di individuare tutte le istanze qualificanti e un ciclo “while” indica al programma di eseguire il ciclo solo finché la condizione indicata è valida. Si potrebbe dire che una chiamata ricorsiva combini alcune delle caratteristiche di questi cicli con un’istruzione “if-then-else”; se questa condizione è vera, allora fai questo, oppure fai qualcosa di diverso se la condizione è falsa. Tuttavia, la ricorsione in genere consente un codice più compatto e consente di passare il problema alla funzione più vicino al punto in cui è necessario.