Quando sentiamo parlare di “programmazione” la maggior parte dei non addetti ai lavori pensa a qualcosa di estremamente complesso. Invece, immaginate per un momento di dover scrivere una ricetta per fare una torta, in termini così chiari e precisi che persino un robot possa eseguirla senza errori. Bene, questa è in fondo l’essenza della programmazione: dare istruzioni a un computer. Ma come si fa? Ci sono diversi “modi di cucina”, se vogliamo, e due dei più discusse sono la programmazione funzionale e quella imperativa. Vediamo insieme in che cosa differiscono.
La programmazione imperativa è come una ricetta fatta di passaggi sequenziali: si dice al computer cosa fare, in che ordine eseguirlo, e si tiene traccia dell'”ambiente da cucina” passo dopo passo. Immaginate di avere una serie di istruzioni quali: “Monta gli albumi a neve”, poi “Mescola la farina” e così via. Quindi, ogni passaggio della ricetta cambia in qualche modo lo stato della nostra cucina e, passo dopo passo, arriviamo al risultato finale: la torta.
Esempi noti di linguaggi di programmazione imperativa sono il C, Java e Python. Nella programmazione imperativa, si può pensare a ogni applicazione come a un grande elenco di compiti eseguiti l’uno dopo l’altro, dove i dati possono essere modificati liberamente da ogni parte del programma, in qualsiasi momento.
La programmazione funzionale, d’altra parte, segue un approccio diverso. Usando la nostra metafora della cucina, è come se preparassimo ogni parte della torta separatamente, in piccole ciotole che non possono essere modificate una volta preparate. Questo significa che, se qualcosa va male, possiamo semplicemente rifare quella specifica parte senza dover ricominciare dall’inizio.
Anch’essa ha linguaggi specifici, come Haskell o Erlang, ma anche Java e Python in certa misura supportano questo approccio. In questi linguaggi, le funzioni sono gli ingredienti principali: vengono chiamate con un set di input e producono sempre lo stesso output senza “sporcare” l’ambiente attorno a loro – senza modificare i dati esterni. Questo rende il programma più facile da testare e da comprendere, dal momento che ogni parte è ben isolata e funziona indipendentemente dalle altre.
Un altro punto fondamentale della programmazione funzionale è l’immutabilità, che è la tendenza a creare nuovi dati anziché modificare quelli esistenti. Pensate a un foglio di appunti dove anziché cancellare scrivete ogni volta su una pagina pulita; così, potete sempre vedere la cronologia dei vostri appunti senza perdervi nulla.
La differenza tra questi due approcci risiede, quindi, principalmente nel modo in cui gestiscono i dati e i loro cambiamenti. Mentre la programmazione imperativa manipola variabili e stati (come aggiornare gli ingredienti della nostra torta in corso d’opera), la programmazione funzionale punta a una serie di funzioni “pure” che non cambiare lo stato del programma e lavorano sempre sugli input per produrre nuovi dati senza side-effect (come una ricetta dove si aprono nuove confezioni anziché riutilizzare gli ingredienti già in uso).
Inoltre, un principio centrale della programmazione funzionale è quello di utilizzare operazioni su collezioni di dati, come le liste, attraverso concetti come ‘map’, ‘filter’ e ‘reduce’. ‘Map’, ad esempio, potrebbe essere visto come il prendere una lista di ingredienti e applicare una stessa operazione, come tagliarli a fette, a ognuno di essi. ‘Filter’ seleziona alcune parti di una lista che soddisfano un certo criterio, come scegliere solo i pezzi di frutta più maturi, mentre ‘reduce’ combina tutti gli elementi di una lista in un’unica entità, proprio come mescolare diversi ingredienti in una ciotola per formare un composto omogeneo.
Capire la programmazione funzionale può sembrare arduo, ma una volta afferrate le basi, questa può diventare un’ottima alleata nella scrittura di codice chiaro, facilmente testabile e espandibile. E, in un mondo dove il codice diventa sempre più complesso e intrecciato, avere spezzoni di logica chiara e ben confinata non è solo bello, ma quasi necessario.
COMMENTI