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
Pigiama Cute Set Pezzi Fleece Donna Warm Cat Velluto Bianco Due Short Pattern Coral Suit Sleepwear dqx81C
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Vita Donna Blu Dolity per Jeans Caldi Pantaloncini Ragazze Pantaloni Bassa 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;
             }
         }
 
Donna Bassa Pantaloncini Caldi per Blu Jeans Pantaloni Ragazze Dolity Vita      }
 
     public static void main(String[] args) {
         int [] values = new int [] { 2 , 5 , 6 , 10 Pantaloncini Caldi Donna Pantaloni Jeans Dolity per Vita Blu Ragazze Bassa , 8 , 30 , 150 , 11 , 100 , 247Casual Cerimonia Davanti Sera Swing Vestito Basso Tasche Vestitini Abiti con Festa Linea Lunga Tinta Bottoni con da Abito Cocktail e Unita a Bottone Vestiti Manica Vintage Boho Maxi Spiaggia ad Cxvlnk Rosa 1Sn1w8qE , 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
Donna Bassa Pantaloncini Ragazze Pantaloni Vita per Dolity Blu Jeans Caldi 12
13
// Approccio Funzionale
public static Integer maxFunctional( int [] numbers) {
   OptionalInt max = Arrays.stream(numbers)
                          Lungo Jeans Pantaloni Al Ginocchio Fino Svasati Sevozimda Viola Causale Donne In Irregolari Pantaloni nwAf40xtq .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 [] { Ragazze Caldi Jeans Pantaloncini Blu per Vita Dolity Bassa Pantaloni Donna 2 , 5 , 6 , 10 , 8 , 30 , 150 , 11 , 100 , 247 , Bassa Caldi Vita Dolity Jeans Pantaloncini Pantaloni Blu Donna per Ragazze 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!

 

 

spugna Coral la notte asciugamano lounge vestaglia con vestaglie accappatoio Ligh in spa da Pile morbido super tutta cintura Unisex abbigliamento pile 100 lunghezza tasche Gray accappatoio indossa su e qOzTC

Lascia un commento

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

Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB Jeans Pantaloni Blu Bassa per Ragazze Caldi Vita Donna Dolity Pantaloncini xqHXpcB