Alessio Biancalana Grab The Blaster di Alessio Biancalana

Elixir per idioti /6, sua maestà il pattern matching

Visto che nell’ultimo episodio abbiamo parlato di pipe operator, con cui cominciamo ad affrontare sul serio l’espressività di un linguaggio funzionale, andiamo a parare sull’ultimo ostacolo che ci separa dall’avere ogni base per cominciare a praticare il nostro Elixir-jutsu in maniera efficace. Sto parlando della feature che ogni linguaggio funzionale porta con sé, da Erlang a Scala al nostro Elixir, ovvero il pattern matching.

È più facile a farsi che a dirsi (o spiegarsi), ma ci proverò lo stesso con qualche parola astrusa: Elixir possiede la capacità di lasciarci definire più “clause”, ovvero funzioni o altri tipi di espressioni, per poi decidere lui stesso quale definizione tra quelle che abbiamo scritto si applica in maniera più vicina all’input che viene dall’esterno. Ripeto: possiamo definire più casi in base a molteplici input, e il runtime provvede ad identificare la forma più vicina di volta in volta all’input fornito per poi comportarsi di conseguenza. Ma a questo punto facciamo prima a vedere un esempio pratico. Un modulo può avere più di una definizione della stessa funzione in base all’input:

iex(1)> defmodule SalutePeople do
...(1)>   def hello("Alessio") do
...(1)>     IO.puts("Hello Alessio")
...(1)>   end
...(1)>
...(1)>   def hello("Agnese") do
...(1)>     IO.puts("Hello my love")
...(1)>   end
...(1)>
...(1)>   def hello(_anyone) do
...(1)>     IO.puts("Who the fuck are you?")
...(1)>   end
...(1)> end
{:module, SalutePeople,
 <<70, 79, 82, 49, 0, 0, 5, 28, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 147,
   0, 0, 0, 15, 19, 69, 108, 105, 120, 105, 114, 46, 83, 97, 108, 117, 116, 101,
   80, 101, 111, 112, 108, 101, 8, 95, 95, ...>>, {:hello, 1}}

Definendo un modulo così, cosa otteniamo? Otteniamo una funzione hello che si comporta diversamente di fronte a me, alla mia ragazza, o davanti a chiunque altro.

iex(2)> SalutePeople.hello("Alessio")
Hello Alessio
:ok
iex(3)> SalutePeople.hello("Agnese")
Hello my love
:ok
iex(4)> SalutePeople.hello("Chiunque altro")
Who the fuck are you?
:ok
iex(5)>

Il pattern matching ci permette di specificare in maniera performante ed efficace come i nostri programmi si devono comportare in base a diversi input. Possiamo usare questa caratteristica non solo nelle firme delle funzioni (le firme sono quella sintassi def tiziocaio(argomento) do ... end) ma anche nei nostri case statement. Normalmente, in linguaggi come JavaScript o Ruby, gli swith case non sono altro che delle maniere leggermente più tollerabili (e dipende anche dai casi) di scrivere una scala a pioli di if else. Nei linguaggi come Elixir abbiamo il pattern matching come arma definitiva per renderli molto più potenti. Prendo il primo esempio che mi capita a tiro dal manuale di Elixir:

iex> case {1, 2, 3} do
...>   {4, 5, 6} ->
...>     "This clause won't match"
...>   {1, x, 3} ->
...>     "This clause will match and bind x to 2 in this clause"
...>   _ ->
...>     "This clause would match any value"
...> end
"This clause will match and bind x to 2 in this clause"

In pratica rispetto a differenti pattern, il runtime come abbiamo già detto è in grado di riconoscere quello che si avvicina di più al caso corrente. In caso di mancato riconoscimento di un pattern, viene applicata la soluzione più generica, che in un case statement viene indicata con l’underscore come possiamo vedere dall’esempio.

Vai alla parte 5

Vai alla parte 7

Paura e delirio nel mondo delle telco, ma WindTre resta calma

WindTre resta ferma sul suo posizionamento mentre Vodafone sforna Ho e TIM sforna KENA Mobile

L’arrivo di Iliad all’interno dell’ecosistema formato dalle telco italiane è stato un piccolo sconvolgimento. Non siamo nuovi a tariffe al ribasso e slogan “da acchiappo”, ma l’arrivo di un nuovo operatore è sempre rivestito da un’aura di mistero, hype, e quando poi il velo di Maya si rompe c’è lo scompiglio.

In risposta all’arrivo di Iliad:

  • Vodafone ha lanciato il suo nuovo brand Ho;
  • TIM ha lanciato il nuovo operatore KENA;
  • WindTre, viceversa, dimostra l’atteggiamento opposto proseguendo il suo percorso senza lanciare nulla di nuovo.

A questo proposito, ci sono una serie di considerazioni da fare: la prima è puramente commerciale, ovvero che una volta superata l’iniziale fascinazione per un nuovo brand più fresco, mi chiedo cosa potrebbe pensare un consumatore di aziende che non fanno altro che inseguire, sfornando qualcosa di nuovo solo perché un altro player ha affrontato il mercato in maniera più aggressiva. La seconda è che “brand nuovo, ma anche no”: un sito fatto in maniera diversa, dei caratteri più arrotondati e delle tariffe da acchiappo non significano necessariamente un rinnovamento infrastrutturale anzi. E cosa ottengono in più i clienti che rimangono con il brand principale anziché affidarsi al nuovo brand che costa meno? Che penalità hanno i clienti di questi nuovi operatori che poi tanto nuovi non sono? Quello che emerge guardando il mercato è solo tanta confusione indotta dalla moltiplicazione di pani, pesci, operatori di telefonia mobile e schede SIM in casa della gente.

In questo panorama va a configurarsi in maniera totalmente diversa WindTre, che non approfitta della confusione del momento per offrire al consumatore qualcosa di nebuloso e confusionario, anzi: attraverso i due storici marchi, Wind e 3 propone ai suoi clienti un’offerta chiara in mezzo al marasma di “nuovi” brand. Sembra quasi una strategia: ricambiare il consumatore con trasparenza e sincerità nelle offerte contrattuali comportandosi con costanza, mentre tutti gli altri cercano solo di fare il verso all’ultimo arrivato producendo una bagarre incredibile. Anche perché poi chi va a perderci, in un modo o nell’altro, è proprio il frastornato cliente.

Elixir per idioti /5, pipe operator e pipeline di funzioni

Quando ho approcciato Elixir per la prima volta, una tra le cose più complicate con cui ho avuto a che fare è stata proprio l’abituarmi a leggere il codice di altri e a capire alcune particolarità del linguaggio, una su tutte il pipe operator. Ve l’ho mostrato nello scorso episodio: il pipe operator (|>) è un operatore particolare che permette di passare l’output di una funzione direttamente alla funzione successiva come primo argomento.

Questo significa che noi possiamo scrivere qualcosa di questo tipo:

IO.puts(divide_by_two(square(10)))

In una forma migliore, che è questa:

10 |> square() |> divide_by_two() |> IO.puts()

E possiamo anche formattarlo perché sia più ordinato:

10
|> square()
|> divide_by_two()
|> IO.puts()

Il funzionamento del pipe operator è abbastanza semplice, si tratta solo di prenderci la mano e di cominciare a “pensare per pipeline”, ovvero immaginare il proprio codice come una sequenza di funzioni per cui l’argomento iniziale che noi forniamo passa attraverso, esattamente come una catena di montaggio, e viene di volta in volta “evoluto” in qualcos’altro.

Personalmente questo concetto di pipeline è qualcosa che mi piace molto, perché permette di architettare il codice in maniera migliore e soprattutto di giocare alle scatole cinesi, per cui una funzione può semplicemente assumere la forma di una grossissima catena di montaggio:

def huge_pipeline(number) do
  number
  |> some_function()
  |> some_other_function()
  |> wow()
  |> such()
  |> code()
end

Ogni funzione di quelle che abbiamo indicato applicherà le sue modifiche al numero in entrata e l’output come abbiamo detto verrà passato alla successiva. Facile no? Proviamo a definire qualche funzione e a giocare col pipe operator per capire meglio.

iex(1)> defmodule SimpleMath do
...(1)>   def square(number), do: number*number
...(1)>   def divide_by_two(number), do: number/2
...(1)> end
{:module, SimpleMath,
 <<70, 79, 82, 49, 0, 0, 4, 196, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 147,
   0, 0, 0, 15, 17, 69, 108, 105, 120, 105, 114, 46, 83, 105, 109, 112, 108,
   101, 77, 97, 116, 104, 8, 95, 95, 105, 110, ...>>, {:divide_by_two, 1}}
iex(2)> SimpleMath.square(2)
4
iex(3)> defmodule HugeModule do
...(3)>   def great_function(number) do
...(3)>     number
...(3)>     |> SimpleMath.square()
...(3)>     |> SimpleMath.divide_by_two()
...(3)>   end
...(3)> end
{:module, HugeModule,
 <<70, 79, 82, 49, 0, 0, 4, 152, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 178,
   0, 0, 0, 16, 17, 69, 108, 105, 120, 105, 114, 46, 72, 117, 103, 101, 77, 111,
   100, 117, 108, 101, 8, 95, 95, 105, 110, ...>>, {:great_function, 1}}
iex(4)> HugeModule.great_function(5)
12.5
iex(5)> HugeModule.great_function(20)
200.0
iex(6)>

Ok, ce l’ho fatta. Giuro che non sto barando, ho scritto ‘sto polpettone nella shell di Elixir, iex, di cui vi ho già parlato.

Quello che ho appena fatto è molto semplice ma secondo me fa capire bene cosa abbiamo davanti: ho scritto un modulo SimpleMath simile a quello dell’episodio precedente, dopodiché in un altro modulo (per comodità) ho riusato queste funzioni definite precedentemente orchestrando una pipeline composta da queste due procedure e il classico valore in input.

Ci siamo. Se avete afferrato come funziona il pipe operator, siete pronti per la prossima grande avventura, ovvero il pattern matching.

Vai alla parte 4

Vai alla parte 6

Elixir per idioti /4, definire moduli e funzioni

La scorsa volta, che ormai è stata un po’ di tempo fa, avevamo visto come operare sulle liste tramite le funzioni messe a disposizione dal modulo Enum. Un modulo non è altro che una raccolta di funzioni, come una scatola degli attrezzi; possiamo usare i moduli per organizzare meglio il nostro codice e raggruppare le funzioni che scriviamo per affinità. Adesso riprendiamo le basi del linguaggio e poniamoci una domanda: cosa succederebbe se io volessi scrivere un modulo tutto mio con blackjack e squillo di lusso in cui raggruppare le mie funzioni?

È abbastanza semplice, ci basta usare defmodule. Un modulo Elixir ha questa faccia:

defmodule Hello do
  def salute(name) do
    IO.puts("I salute you, " <> name)
  end

  def sayhello(name) do
    IO.puts("Hello, " <> name)
  end
end

Insieme a defmodule stiamo imparando anche come definire delle funzioni. Una funzione in Elixir si compone della keyword def, un nome, e degli argomenti (quelli passati tra parentesi). In seguito possiamo richiamare le funzioni del modulo che abbiamo definito in questo modo:

Hello.salute("Alessio")

E otterremo che venga stampato a schermo un saluto col nostro nome, come da codice. Se vogliamo provare a giocare un po’ con la definizione dei moduli possiamo buttare giù uno script Elixir al volo, creando un file chiamato hello.exs con questo contenuto:

defmodule Hello do
  def salute(name) do
    IO.puts("I salute you, #{name}")
  end

  def sayhello(name) do
    IO.puts("Hello, #{name}")
  end
end

Hello.salute("Alessio")
Hello.sayhello("Arcibaldo")

Per eseguirlo ci basta spostarci nella directory dove si trova e lanciarlo con il comando elixir:

$ elixir hello.exs
I salute you, Alessio
Hello, Arcibaldo

Possiamo definire quanti moduli vogliamo. In uno script piccolo di un solo file fatichiamo a vedere l’utilità di una cosa simile, ma quando abbiamo tanti file e un progetto che comincia ad assumere una stazza importante, l’ordine è fondamentale. Per quanto riguarda la creazione di un nuovo progetto (non uno script piccolino, proprio un progetto di quelli potenzialmente grandi) da zero vi rimando al post di Francesco, che illustra molto bene il tool che viene usato per gestire i progetti in Elixir, Mix, insieme al suo uso più comune, ovvero mix new.

La keyword return in Elixir

Vale la pena spendere due parole, dato che stiamo parlando per la prima volta davvero di funzioni, su come definire i valori di ritorno delle proprie funzioni in Elixir. Al posto di usare return come in tantissimi altri linguaggi, tra cui JavaScript, Java, o Ruby, in Elixir il valore di ritorno di una funzione è semplicemente l’ultima espressione che scriviamo dentro di essa.

Per dare un occhio più approfondito a questa piccola particolarità possiamo definire un modulo che si occupi di fare piccole operazioni sui numeri:

defmodule SimpleMath do
  def divide_by_two(number) do
    number/2
  end

  def square(number) do
    number*number
  end

  def sum_three(number) do
    number+3
  end
end

Salvando questo modulo come simple_math.ex possiamo caricarlo dentro iex e farci degli esperimenti:

iex(1)> import_file("simple_math.ex")
{:module, SimpleMath,
 <<70, 79, 82, 49, 0, 0, 5, 56, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 159,
   0, 0, 0, 17, 17, 69, 108, 105, 120, 105, 114, 46, 83, 105, 109, 112, 108,
   101, 77, 97, 116, 104, 8, 95, 95, 105, 110, ...>>, {:sum_three, 1}}
iex(2)> 4 |> SimpleMath.divide_by_two |> IO.puts
2.0
:ok
iex(3)>

Come vediamo, all’interno delle funzioni ci basta usare un’espressione per identificarla come valore di ritorno. Se volessimo la stringa ciao come valore di ritorno, non dovremmo fare altro che scrivere "ciao" alla fine della funzione. Per chi viene da altri linguaggi questa è una differenza non da poco, dato che Elixir non è strutturato per permettere per esempio i cosiddetti “early return”1 all’interno delle funzioni. Io però con questo meccanismo ho preso confidenza abbastanza in fretta.

Adesso che sappiamo come definire funzioni ma soprattutto come definire moduli dove raccogliere le nostre funzioni, possiamo mantenere il codice ordinato. Non ci resta altro che cominciare con qualche piccolo progettino2.

Vai alla parte 3

Vai alla parte 5

  1. Per chi volesse approfondire, un buon esempio di early return in JavaScript è qua. È una tecnica che uso anch’io, ma in Elixir non si può, e non solo: in realtà per come è strutturato il linguaggio penso aiuti a fattorizzare meglio il codice. Se ne volete parlare, meglio scrivermi o venire al prossimo incontro di Elixir Roma ;-) 

  2. In realtà manca ancora un piccolo pezzettino, confido che lo vedremo presto. Avete visto la piccola magia che ho fatto dentro iex nell’ultimo snippet di codice? Si chiama pipe operator. Ma ne parleremo meglio la prossima volta. 

React Europe 2018: riportando tutto a casa

React Europe 2018 with some lovely aliens

Sono passate un po’ di settimane e ho sedimentato quello che ho visto andando a React Europe (grazie ad AdEspresso, che mi ha pagato viaggio e biglietto). Oltre i francesi che parlano come sempre un pessimo inglese e come di consueto fingono persino di non capire quando qualcuno tenta di chiedergli qualcosa che non sia “water”, in realtà ho visto parecchie cose riguardanti React e non solo; e adesso mi riporto tutto a casa, in una parafrasi del titolo del primo disco dei Modena City Ramblers che belli ma non ci vivrei quanto ci pare, ma è stato uno dei dischi della mia formazione e quindi ve lo beccate.

È stata una bellissima conferenza, che mi ha fatto soprattutto misurare le competenze che ho acquisito nel tempo su questa libreria e su questo stack (Redux et similia), facendomi rendere conto sia di quanto io valga come sviluppatore React, sia di quanta strada io debba ancora fare prima di potermi considerare come uno che ha una conoscenza approfondita di come funziona React al suo interno. Ho anche notato che per mia fortuna ho dei colleghi che sono in grado di insegnarmi ogni giorno qualcosa di nuovo.

React Europe 2018: the stage

La sessione di keynote di Ken Wheeler

Il mio talk preferito è stato la sessione di keynote di Ken. Ho conosciuto Ken l’anno scorso durante il mio giro a Redmond per Build, e devo dire che sono rimasto impressionato da due cose: è l’unica persona oltre Sean Larkin che mi abbia mai consigliato di provare a scrivere un plugin per webpack, ma soprattutto è un adorabile americanissimo patriotticissimo cialtrone.

Ken Wheeler && React 16

Con il suo savoir faire ci ha introdotto le novità di React 16, le nuove API (tra cui la Context API, che passa da essere etichettata come magia nera ad essere un cittadino di prima classe), tutto applicato ad un caso di studio dove trasformava un e-commerce di baguette in un e-commerce di pane in cassetta statunitense con tanto di stelle e strisce sullo sfondo. Ha fatto ridere ed è stato d’impatto – quasi come beccarlo a pranzo e vedere che si ricordava di me.

I trend: CSS in JS e render props

CSS-in-JS è un trend che nella community React ha sempre fatto discutere. Anche quest’anno, con la fioritura di un sacco di librerie dedicate a questo paradigma che consente di includere il codice dello stile CSS di un elemento all’interno del suo codice JavaScript, abbiamo avuto di che parlare insieme a tutti gli speaker. Chiunque parlasse di CSS ha menzionato l’uso di una libreria CSS-in-JS; il discorso nel suo complesso è troppo ampio per essere affrontato in questo post, ma direi che anche se ormai è stato sdoganato come sia possibile programmare secondo questo approccio e questa organizzazione, larga parte della community ha ancora le sue perplessità e in tanti utilizzano ancora Sass e CSS legacy standalone.

L’altro trend su cui non ho visto nessuno speaker fare silenzio (circa) è quello delle render props. L’anno scorso Michael Jackson, l’autore di React Router, ha tenuto un talk in cui spiegava come secondo lui i componenti di alto ordine fossero sopravvalutati e secondo lui non risolvessero il mistero principale che è quello della fonte di provenienza dei dati su cui fare logica mentre si sviluppa un componente. Contestualmente ha introdotto il concetto di render prop, ovvero una prop di un componente che non fa altro che eseguire una funzione passando in input dei valori relativi allo stato interno di quel componente stesso.

Questo permette, avendo un componente con una sua logica di stato, di iniettare il comportamento di rendering dall’esterno. È interessante, e in AdEspresso abbiamo cominciato già da un po’ ad usare le render prop per i nostri componenti: devo dire che una volta afferrato il concetto (che di suo è semplice per chi ha una conoscenza di React superiore all’hello world) ci si abitua in fretta e il codice finale risulta molto pulito.

Team come quello di Apollo hanno riscritto la propria suite di componenti React passando da un approccio basato sugli higher order component a un approccio basato su render props. Gli esempi che sono stati fatti live mi hanno convinto che sia un approccio virtuoso, anche se come sempre non esiste né il martello d’oro né il proiettile d’argento.

Varie ed eventuali: la Francia, il cibo

Parigi è un posto particolare, accattivante, con uno stile tutto suo. Personalmente ho trovato modo di scontrarmi con i francesi anche nelle piccole cose, e ho trovato chi effettivamente ha finto di non parlare una parola di inglese davanti a me, chi veramente non lo parlava, e chi non mi ha rivolto la parola per i motivi più bislacchi. Nonostante la fauna, il posto è accattivante e ho capito due cose: la prima è che ci dovrò tornare, dato che non ho trovato il tempo né le forze di andare in centro a visitare posti come Notre-Dame; la seconda è che anche se a me non è piaciuta molto (per il poco che ho visto), capisco benissimo chi la ama alla follia data la sua particolarità anche nelle minuzie di una periferia come quella di Charenton-le-Pont dove eravamo noi.

Charenton-le-pont

Lo so che è come giudicare Roma andando solo al centro commerciale Roma Est, ma questi sono gli strumenti euristici che ho. Accontentatevi.

Charenton-le-pont skyline

La conferenza nel suo complesso invece non solo ha esibito dei talk e degli speaker di grandissima qualità, ma è la prima convention di sviluppatori dove (perdonate la trivialità, lo so) vedo offrire un buffet di cibi tipici di una qualità veramente sopraffina, tra panini al fois gras, salmone affumicato e non, altri tipi di pesce, quiche mastodontiche e una selezione di formaggi da far girare la testa.

Il primo giorno tra i miei gusti non proprio facilissimi in fatto di pesce e il fatto che oggettivamente il pranzo è stato meno particolare, il mio piatto è stato il tipico piatto da conferenza.

React Europe 2018, giorno 1: il cibo

Il secondo giorno invece tra i mini hamburger di manzo e di salmone cucinati sul momento, il salmone e una generale maggiore varietà io, Gabriele, Mattia e Andrea abbiamo opposto molta meno resistenza al preludio dell’abbiocco post-prandiale. Che, sì, è un modo molto colto per dire che ci siamo sfondati di cibo.

React Europe 2018: un food post

Ma consentitemi di riprendere l’argomento francesi e spocchia per un paragrafo almeno: è mai possibile che alla domanda “do you speak english?” si abbia come unica risposta uno sguardo scocciato? È mai possibile che visto un turista palesemente estero lo si approcci parlando solo in francese e anche in maniera piuttosto incomprensibile per uno che ha orecchio verso un sacco di lingue? Ma soprattutto, è mai possibile che per le dieci di sera chiudano tutti i posti che ti possono dare un minimo di conforto culinario? Io questo non lo so, buona serata a tutti. Quello che so è che il mix di bellezza architettonica, spocchia degli autoctoni e cucina oggettivamente caratteristica, buona e varia, fa sì che Parigi ti rimanga nel cuore a prescindere dal sentimento negativo o positivo che susciti, come una sorta di post-it con scritto “ricordati che sei stato qui”.

Street photography in giro per Parigi a gradire

E anche se quando i francesi parlano inglese non si capisce un benemerito, anche se sono andato a letto senza una cena che non fosse un pacchetto di patatine, anche se ho appurato che i parigini1 a domanda non rispondono affatto, mi porterò sempre dietro quanto mi sono divertito, quante cose assurde ho visto (come la replicazione di un event store basato su Redux attraverso nodi multipli), e quante persone fantastiche ho incontrato2.

Charenton Ecoles

  1. Anche se credo che i parigini veri definirebbero quelli che ho incontrato io dei provincialotti. Tuttavia, penso che cambiando l’ordine dei francesi il risultato non cambi. 

  2. Primi fra tutti i miei colleghi Gabriele, Mattia e Andrea. Un cuore per voi ragazzi, siete stati dei compagni di conferenza fantastici!