Skip to main content
Numbers

A proposito di Functional Programming: filtrare un Array in Swift

Swift è un linguaggio pensato per la programmazione funzionale. Si tratta di un potente paradigma dichiarativo le cui origini risalgono alla nascita del lambda calcolo negli anni 30 del secolo scorso e la cui idea base è quella di intendere il software come la valutazione di espressioni matematiche.

Per tanti anni il paradigma imperativo (opposto al dichiarativo) è stato nettamente più popolare nello sviluppo software ma le cose stanno cambiando e l’idea di spiegare in questo articolo come usare il metodo filter è solo un pretesto per parlare di Functional Programming 🙂

Un aspetto della functional programming è la possibilità passare funzioni come parametri ad altre funzioni (o metodi).

Una lista di numeri

La struttura Array in Swift (perché, ricordiamo, si tratta di una Struct e non di una Class) espone il metodo filter definito come segue:

Il metodo riceve come parametro una funzione includeElement e restituisce un Array dello stesso tipo dell’array corrente.

La funzione includeElement riceve come parametro un element di tipo T (lo stesso tipo degli elementi dell’array corrente quindi) e restituisce un valore boolean.

Vediamo come utilizzare filter. Costruiamo un semplice array di interi.

Ora definiamo una funzione che riceve come parametro un intero e restituisce true se si tratta di un numero pari, false altrimenti e passiamola al metodo filter.

Funziona! Il metodo filter ha applicato la funzione isEven a ogni elemento dell’array ed ha restituito un nuovo array (dello stesso tipo) contenente solo quegli elementi per cui isEven è true.

La parte in cui ogni elemento dell’array viene effettivamente letto è completamente trasparente allo sviluppatore. Non è stato necessario scrivere alcun ciclo for. Ci siamo concentrati sulla logica relativa a come volevamo che fosse fatto il risultato, non tanto a come ottenerlo. E’ un segnale forte che siamo vicini al paradigma della Functional Programming. Andiamo più a fondo.

Closures

Non è strettamente necessario dichiarare una funzione separatamente, infatti possiamo inserire la logica della funzione direttamente nella chiamata a filter. In questo caso stiamo scrivendo una closure, ovvero un blocco di codice che può essere passato tra vari parti del programma.

La closure è definita tra le 2 parentesi graffe:

  • La parte che precede la keyword in dichiara i parametri ricevuti in input e il tipo di ritorno
  • La parte contenuto tra in e } invece contiene la logica della funzione.

Se osservate bene vedrete che è molto simile a quella dell’esempio precedente. In questo caso non è presente la keyword func e il nome della funzione.

Type inference

Il compilatore di Swift è in grado di dedurre il tipo del parametro della nostra closure. Se la closure deve essere eseguita su ogni elemento dell’array numbers e si tratta di un array di Int, allora è evidente che la closure riceverà un Int come parametro. Inoltre il metodo filter dichiara esplicitamente che la closure deve restituire un Bool.

Quindi possiamo eliminare la parte in cui dichiariamo i parametri di input e il tipo di ritorno della closure.

Nel codice precedente, avendo rimosso la dichiarazione dei parametri ricevuti dalla closure non possiamo più usare number per identificare il parametro. In questo caso possiamo usare $0 per indicare il primo parametro ricevuto. Nel caso in cui la closure avesse ricevuto più parametri avremmo potuto riferirci a loro con $1 (per il secondo parametro), $2 (per il terzo) e così via.

Trailing closures

Swift è uno dei linguaggi più essenziali esistenti. Abbiamo già visto come permette di eliminare tutto ciò che è ridondante da un blocco di codice e lasciare solo il minimo indispensabile. C’è un ultimo passo che possiamo fare.

Se una closure è l’ultimo parametro ricevuto da un metodo (e in questo caso lo è) allora possiamo invocare invocare il metodo con la tecnica della trailing closure. Basta invocare il metodo normalmente e poi aggiungere {} contenenti il codice della closure.

Ancora una volta viene restituito un nuovo Array contenete gli interi 2, 4 e 6.

Conclusione

L’ultimo blocco di codice è un ottimo esempio di Functional Programming. L’aspetto dichiarativo è predominante e discapito del lato imperativo. Qualunque sia il linguaggio che utilizzate maggiormente oggi vale la pena approfondire gli aspetti della programmazione funzionale perché è probabile che nei prossimi anni assuma un ruolo sempre più importante nel contesto del sviluppo software.

Insomma preparatevi a scrivere codice concentrandovi su come deve fatto il risultato invece di indicare come costruirlo.

Luca Angeletti

Trainer • Developer • Writer

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *