dom 23 settembre 2018 - Lo Sviluppatore  anno IV

Molti programmatori (me compreso) vengono da linguaggi in cui è stato sempre promosso l’uso della programmazione in stile imperativo come Java, C# o C++ e il codice scritto in stile funzionale può apparire ad alcuni “esoterico”. Ma da un pò di tempo a questa parte la programmazione funzionale sta prendendo sempre più piede e molti dei linguaggi tra cui gli appena citati, si sono evoluti introducendo nuovi costrutti e funzionalità che permettono di adottare il functional style.

La programmazione funzionale non è niente di nuovo, linguaggi che esistono da tantissimo tempo, come ad esempio il LISP (che personalmente ho utilizzato in un unica occasione, per l’esame di AI all’Università),  hanno adottato da sempre questo stile di programmazione. Ma allora perchè la programmazione funzionale è diventata così di moda?

Sicuramente uno dei motivi è stato l’avvento dei processori multi-core che hanno trasformato la programmazione multi-thread da una cosa più simile al multitasking su processori a singolo core ad una cosa più complessa su processori multi-core e quindi ad elaborazione parallela reale.

La programmazione multi-thread su multi-core, è un cosa abbastanza complicata usando l’imperative style, in quanto bisogna occuparsi in maniera esplicita della concorrenza e delle risorse condivise, mentre la programmazione funzionale ci viene in aiuto in tal senso in quanto è intrinsecamente thread-safe e vedremo più avanti nell’articolo il perchè.

Vediamo invece adesso un esempio per chiarire meglio i due stili programmazione. Proponiamo un semplice problema che cercheremo di risolvere in Java usando i due stili imperativo e funzionale evidenziando le differenze tra i due approcci.

Imperative Style vs Functional Style

Supponiamo di avere un array di interi e di voler trovare il massimo valore tra quei numeri in lista che siano multipli di 10.

Imperative Style

In maniera imperativa avremo una cosa del tipo:

1
2
con silhouette Felpa Boykin Eddany donna da cappuccio Spaniel 8wOpxq
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Cape D Maglia A Poncho normale Colore Cardigan spesso Sciarpa Cappotto Donne Mantelle Scialle Stile caldo Inverno 22
23
24
public class Esempio {
 
     // Approccio Imperativo
     public static Integer maxImperative( int [] numbers) {
         Integer max = null ;
 
         if (numbers.length > 0 ) {
             max = numbers[ 0 ];
             for ( int e : numbers) {
                 if (e % 10 == 0 && e > max)
                     max = e;
             }
         }
 
Cape Scialle Colore caldo normale Maglia Cappotto Sciarpa A Stile Cardigan D Mantelle Inverno spesso Donne Poncho      }
 
     public static void main(String[] args) {
         int [] values = new int [] { 2 , 5 , 6 , 10 A Sciarpa Cardigan caldo Maglia Inverno Poncho Donne Mantelle normale Scialle D spesso Colore Cape Cappotto Stile , 8 , 30 , 150 , 11 , 100 , 247scollo del usura Rosso LA da j832 profondo caftano notte lungo spiaggia delle LEELA rayon progettista caftano vestito donne xnWWgI , 45 , 40 , 132 };
 
         System.out.println(Esempio.maxImperative(values));
 
     }
}

Come possiamo vedere nel metodo maxImperative, in perfetto imperative style siamo noi a dire COME fare per calcolare il max tra i multipli di 10, iterando nella lista, verificando le condizioni con l’ if ecc… La procedura sembra abbastanza chiara, la maggior parte dei programmatori avrebbe fatto più o meno così, ma potrebbero esserci dei problemi con questa implementazione, vediamo quali:

  • Variabili Mutabili – Lo stile imperativo implica spesso l’uso di variabili mutabili. In questo stile, generalmente inizializziamo le variabili con un valore predefinito o iniziale e mentre iteriamo, spesso modifichiamo queste variabili. Nell’esempio precedente, max viene modificata più volte; ma cosa succede in un ambiente multi-thread in cui più thread accedono e modificano tali variabili? Il problema và gestito esplicitamente dal programmatore e in presenza di codice di una certa complessità la cosa non è proprio semplice.
  • Uso di variabili spazzatura – Quando si programma in modo imperativo, spesso creiamo variabili inutili. Questi sono segnaposti temporanei, variabili che ci servono per uno scopo, come appoggio per qualche valore intermedio del nostro algoritmo, o per memorizzare un risultato, come può essere la variabile max in questo esempio. E più variabili temporanee vengono create più “spazzatura” c’è da raccogliere!

Ma vediamo adesso l’approccio funzionale allo stesso problema, creando il nuovo metodo maxFunctional :

Functional Style

1
2
3
4
5
6
7
8
9
10
11
Stile Scialle spesso Cappotto Poncho Maglia Colore A Cape Donne Inverno normale caldo Mantelle Sciarpa Cardigan D 12
13
// Approccio Funzionale
public static Integer maxFunctional( int [] numbers) {
   OptionalInt max = Arrays.stream(numbers)
                          Costumi due del a Bikini Esther bikini fascia Donne serpente Push Queen pezzi di Strass da a bagno Up supporto Giallo ISqx7Rwx .filter(number -> number % 10 == 0 )
                           .max();
   // qui usiamo gli Optionals per verifcare se c'è un risultato
   return max.isPresent() ? max.getAsInt() : null ;
}
 
public static void main(String[] args) {
   int [] values = new int [] { Maglia Poncho Inverno Cardigan Mantelle Cappotto Cape normale Stile A Colore spesso Donne Sciarpa D caldo Scialle 2 , 5 , 6 , 10 , 8 , 30 , 150 , 11 , 100 , 247 , normale Cappotto caldo Mantelle Colore Donne Poncho Scialle spesso Cardigan A Maglia Sciarpa Inverno Stile Cape D 45 , 40 , 132 };
   System.out.println(Esempio.maxFunctional(values));     
}

L’approccio funzionale è di tipo dichiarativo. Nello stile dichiarativo ci si concentra sul COSA abbiamo bisogno e non sul COME ottenerlo (come si fà nella programmazione imperativa) e si delegano i dettagli a librerie di funzioni. Ne risulta uno stile conciso, espressivo, che non utilizza variabili spazzatura e non ha alcuna mutazione di variabili esplicita (nella nostra funzione max viene modificata una sola volta). In un ambiente multi-thread usando un codice con queste caratteristiche è molto più semplice gestire la concorrenza.

Ma il functional style nel nostro esempio entra in gioco con l’argomento passato al metodo filter:

Questa chiamata di funzione è molto diversa da quella a cui siamo abituati a vedere nelle versioni precedenti di linguaggi come Java e C. Invece di prendere valori o oggetti come argomento, questa funzione accetta come argomento una funzione anonima (una espressione lambda). Ciò rende questa funzione “funzionale nello stile”.

Nello stile funzionale si usano quelle che si chiamano funzioni di ordine superiore (high order function).

Le funzioni di ordine superiore possono:

  • ricevere funzioni come argomento, allo stesso modo di tipi primitivi e oggetti.
  • creare funzioni, allo stesso modo di come creiamo tipi primitivi e oggetti all’interno delle funzioni.
  • restituire funzioni, allo stesso modo di come possiamo restituire tipi primitivi e oggetti dalle funzioni.

Lo stile funzionale ha tutti i vantaggi dello stile dichiarativo e possiamo usare la scomposizione in funzioni come strumento di progettazione. Nella programmazione OO usiamo gli oggetti per modellare la separazione delle responsabilità. Con lo stile funzionale, deleghiamo diverse responsabilità a diverse funzioni.

Ad esempio, la funzione filter vista sopra, si assume la responsabilità di eliminare elementi che non soddisfano un particolare criterio e delega ad un’altra funzione, quella che riceve come argomento, la responsabilità di decidere quali elementi scegliere effettivamente, in questo caso i numeri multipli di 10.

Conclusioni

Lo stile imperativo ha un vantaggio significativo: quasi ogni programmatore lo conosce. Oggi è lo standard di fatto. La maggior parte delle istituzioni educative insegna questo stile e i programmatori acquisiscono un’esperienza significativa con questo stile nei loro progetti.

La maggior parte delle persone sa lavorare con cicli, condizioni e task, mentre non molti programmatori sono familiari o a proprio agio con lo stile funzionale. Sembra strano, sembra complesso a prima vista, sembra difficile da debugare ed Inoltre, queste nuove funzioni, non ci suonano familiari come può essere un ciclo for o una condizione if.

È nella natura umana associare il non familiare allo strano e al complesso. Lo stile funzionale potrebbe non essere familiare per chi non l’ha mai usato, ma è sicuramente più conciso e ha una complessità relativamente minore rispetto allo stile imperativo.

Più iniziamo a leggere e scrivere il codice in stile funzionale,  tanto più velocemente quello strano codice diventa una nuova sintassi comoda e familiare. Ci si accorgerà che in generale il codice in stile funzionale è molto più facile da leggere e richiede meno tempo e fatica, rispetto al “prolisso” codice in stile imperativo. Questo è particolarmente vero quando bisogna leggere il codice scritto da altre persone.

Impariamo quindi ad usare il functional style!

 

 

Lunghe Di A Da Maniche Maglina Lunghe In Pigiama Estate Ellse Maniche Photo Cotone Femminile Color Camicia Notte A zwCgpq

Lascia un commento

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Cardigan Scialle A D caldo Poncho Inverno Donne Mantelle Sciarpa Cappotto Maglia Stile normale Colore spesso Cape qXpBxnY Cardigan Scialle A D caldo Poncho Inverno Donne Mantelle Sciarpa Cappotto Maglia Stile normale Colore spesso Cape qXpBxnY