La frase è di Abraham Maslow, autorevole psicologo statunitense, e si trova in una sua celebre pubblicazione del 1966. Tradotta e riassunta:
Se hai solo il martello, ogni cosa ti sembra un chiodo.
Ricordiamoci sempre questo concetto quando qualcuno ci propone un'unica ricetta per affrontare una grande varietà di situazioni.
La programmazione funzionale ha origine nel 1930, con Alonzo Church, e il suo calcolo lambda. E già nel 1937 Alan Turing, pioniere britannico dell'informatica, poté dimostrarne l'equivalenza a una Macchina di Turing, dispositivo concettuale che a sua volta è computazionalmente completo, cioè capace di eseguire tutti i compiti realizzabili da un computer.
Leggo talvolta articoli in cui la programmazione funzionale diventa il martello, e le applicazioni informatiche sono tutti chiodi. Questo atteggiamento, ritengo, è più religioso che scientifico. Dovremmo chiederci, per ogni problema, qual'è lo strumento giusto da utilizzare.
La programmazione orientata agli oggetti nasce con il linguaggio Simula nel 1961, e nel 1967 con SmallTalk. Seguono Objective C e C++ a metà degli anni '80, e vari altri, tanto che ormai quasi tutti i linguaggi moderni adottano questo modello.
La capacità della programmazione a oggetti di rappresentare entità, di incapsularne il modello dati e le operazioni, e di permettere vari tipi di relazione tra entità, è un valore secondo me imprescindibile. A maggior ragione con l'introduzione dei tipi generici, a partire dal 1977 con Ada, seguito più tardi da altri linguaggi, per esempio nel 1991 in C++ con i template, nel 2004 in Java con i generics.
Ma per la manipolazione di collezioni di dati, l'approccio funzionale ha indubbiamente una sua utilità, permettendo spesso, con una singola linea di codice, ragionevolmente semplice e espressiva, di svolgere interi algoritmi di selezione, ordinamento e trasformazione dei dati.
La programmazione concorrente (e qui in particolare intendo il multithreading) è un animale potente ma difficile da domare. Permette di eseguire in simultanea diverse attività di elaborazione. La parte difficile inizia quando queste attività devono interagire tra loro, per scambiarsi dati o concorrere all'utilizzo di risorse.
Solo con una solida formazione specifica è possibile utilizzare questa tecnica di programmazione senza incorrere in difetti funzionali gravi, e per loro natura estremamente difficili da riprodurre e diagnosticare. D'altra parte può essere uno strumento estremamente efficace nei sistemi in tempo reale.
Nella programmazione sincrona, se occorre eseguire più attività in simultanea, si ricorre al frazionamento delle attività, e alla loro esecuzione a rotazione. La relativa semplicità è il punto di forza. D'altra parte, ogni attività deve mantenere in maniera esaustiva le informazioni relative al proprio stato di avanzamento. Inoltre, ogni frazione di attività deve svolgersi in un tempo limitato, e se una di esse non rispetta questo vincolo, compromette l'esecuzione di tutte le altre.
La programmazione asincrona consente, entro certi limiti, di parallelizzare le operazioni di elaborazione senza incorrere nelle difficoltà della programmazione concorrente. Specifici costrutti del linguaggio permettono di procedere con l'elaborazione in corso, mentre si attende che determinate operazioni vengano completate: accessi a database o al file system, operazioni di rete, tempi di ritardo, interazione con altri sistemi.
Il meccanismo utilizzato tende a rendere un po' meno chiara la struttura del codice, e inoltre ha la caratteristica di essere contagioso; in parole semplici, se una funzione asincrona interagisce con altre funzioni, anche queste sono generalmente vincolate a essere o diventare asincrone.
Giorgio Barchiesi
Albo degli Ingegneri Sez. A, N. 4027 della Prov. di Trento
P.IVA 02370260222, C.F. BRC GRG 58L26 C794R
Copyright © 2015-2024 Giorgio Barchiesi - Tutti i diritti riservati