Alessio Biancalana Grab The Blaster di Alessio Biancalana

Elixir per idioti /3, Enum e funzioni di Enum

Andando in ordine sparso rispetto alle funzioni messe a disposizione dalla standard library di Elixir, una cosa che adoro letteralmente è il modulo Enum.

Il protocollo Enumerable

La prendo da lontano: il modulo Enum contiene funzioni che posso iterare su qualsiasi tipo, custom e non, che implementi il protocollo Enumerable. Per implementare un protocollo la documentazione ci mette a disposizione tutto ciò che dobbiamo sapere, e ci basta implementare le funzioni che quello specifico protocollo richiede.

Io sono un fan dell’approccio configuration-over-convention, ma in questo caso devo dire che pur con le mie perplessità penso che questo tipo di convention-over-configuration sia il meglio che si possa ottenere senza rischiare di fare casino.

Con convention-over-configuration si fa sempre casino ndr.

Per tantissimi tipi di base, il protocollo Enumerable è già implementato di suo e non dobbiamo assolutamente preoccuparci di scrivere noi le funzioni che consentano al modulo Enum di operare indisturbato; questo significa che la premessa di cui sopra per i non smaliziati è assolutamente inutile, però mi piaceva farla.

E ora, dai con le cose importanti.

Enum

Il modulo Enum serve a fare pressoché qualsiasi operazione di cui abbiamo bisogno su tipi iterabili, come le liste o le mappe. Ci espone un sacco di funzioni, di cui le più importanti “ovviamente” (ovviamente un corno, ma per chi conosce la programmazione funzionale è ovvio) sono map e reduce.

Un esempio:

iex(1)> list = [1, 2, 56, 43, 90]
[1, 2, 56, 43, 90]
iex(2)> Enum.map(list, fn(x) -> x * 2 end)
[2, 4, 112, 86, 180]

Abbiamo dichiarato una lista con dei valori dentro, dopodiché abbiamo mappato la funzione che raddoppia il valore che le diamo in pasto su ogni elemento della lista che abbiamo dichiarato in precedenza. In questo caso abbiamo usato una funzione anonima (ovvero una funzione dichiarata inline a cui non abbiamo dato un nome).

Abbiamo mille altre funzioni per ottenere informazioni sulla nostra lista, come count:

iex(3)> Enum.count(list)
5

O per manipolarla:

iex(4)> Enum.concat(list, [23, 42])
[1, 2, 56, 43, 90, 23, 42]
iex(5)> list
[1, 2, 56, 43, 90]

Notiamo bene che in perfetta linea con l’orientamento funzionale del linguaggio, queste funzioni non modificano il parametro che passiamo in ingresso, ma per esempio per quanto riguarda la nostra lista ne ritornano una nuova. Per mantenere il risultato della nostra concat, dobbiamo quindi dichiarare una nuova lista, e in questo modo potremo fare logica sull’output della funzione.

iex(6)> larger_list = Enum.concat(list, [23, 42])
[1, 2, 56, 43, 90, 23, 42]
iex(7)> larger_list
[1, 2, 56, 43, 90, 23, 42]
iex(8)> Enum.map(larger_list, fn(x) -> x * 3 end)
[3, 6, 168, 129, 270, 69, 126]

Il manuale di Enum è piuttosto vasto. Ve l’ho già detto che userei il manuale di Elixir in generale come lettura della buona notte? La reference di Enum la troviamo qui.

È importante notare come le funzioni, anonime o meno che siano, che passiamo alle funzioni di Enum, possano cambiare leggermente la loro API in funzione del tipo su cui iteriamo. Per esempio per iterare su una mappa abbiamo bisogno di una funzione con ingresso un parametro, una tupla con la chiave e il valore, su cui dentro la funzione che dichiariamo potremo fare logica ovviamente.

iex(9)> map_to_iterate = %{top: 1, lol: "this is a random string"}
%{lol: "this is a random string", top: 1}
iex(10)> Enum.map(map_to_iterate, fn(param) -> IO.inspect(param) end)
{:lol, "this is a random string"}
{:top, 1}
[lol: "this is a random string", top: 1]

In questo caso non abbiamo modificato nulla per cui la funzione ci ha stampato quello che le abbiamo chiesto di stampare (ovvero la tupla in input), e ci ha restituito la mappa convertita in una lista di tuple, che si può consultare nello stesso modo di una mappa standard quindi non ci crea problemi.

Possiamo comunque anche modificare la nostra mappa in ingresso:

iex(11)> Enum.map(map_to_iterate, fn({k, v}) -> {k, "Look! #{v}"} end)
[lol: "Look! this is a random string", top: "Look! 1"]

Ma che cosa abbiamo appena fatto? Abbiamo usato una sintassi molto concisa per dichiarare il valore di ritorno della nostra funzione. Probabilmente ne parleremo di qui a breve: Elixir consente una potenza espressiva notevole, il che significa che in pochissime righe di codice possiamo fare parecchio. Questo significa anche, però, che ad un occhio meno allenato il codice possa risultare meno comprensibile.

Vai alla parte 2

Vai alla parte 4

Non puoi piacere a tutti

Non c’entra molto col tema principale di questo blog ma Raffaele Gaito è una di quelle persone che mi fregio di conoscere da un bel po’ di tempo. Lui ha avuto il suo percorso, io ho avuto il mio, e quando parlo con lui è sempre un piacere confrontarsi, specie perché magari avendo costantemente il pregiudizio causato dal fatto di avere a che fare principalmente con persone orientate alle professioni IT, Raffaele è esattamente quel tipo di persona di cui ho bisogno per riferirmi a lui come un buon punto di vista esterno.

E poi consiglia delle pizze da paura!

Ieri ha pubblicato il suo “7 cose (di business) che ho imparato nel 2017”, e leggendolo ho notato questo:

Poi a un certo punto ti trovi di fronte a un bivio: o impazzisci per stare dietro all’opinione delle persone o realizzi che non puoi piacere a tutti. Passi in modalità “sticazzi, chi mi ama mi segua” e ti accorgi che da un certo punto è inevitabile che il pubblico si spacchi, che la loro opinione diventi polarizzata e che starai antipatico a qualcuno.

Appena l’ho realizzato è stato come aver scoperto le altre marce di una Aston Martin che stavo guidando in prima da troppo tempo.

È vero. Mi ha fatto particolarmente bene leggerlo, perché sono tesissimo dato che domani parlo al Facebook Developer Circle di Roma e sto ancora lavorando alle slide in maniera ossessiva. Mi ha tranquillizzato.

Grazie Raf. 🚀

Elixir 1.6

Elixir 1.6 è fuori, into the wild.

Novità rilevanti:

  • Formatter! Yay!
  • @deprecated e @since per favorire le transizioni tra versioni “breaking” dei moduli
  • IEx adesso integra il formatter e una serie di nuove feature per fare pretty print degli snippet
  • mix xref dà informazioni superfiche su progetto corrente e dipendenze
  • defguard? Le guardie sono un concetto che non ho approfondito, ma potentissime. Adesso possiamo definirle e usarle nella firma delle funzioni. Non capisco bene quanto di questo differisca dal passato.

Per approfondimenti, il post originale è al suo posto (ed è linkato nell’header, come sempre). E ovviamente il manuale!

L'origine del window switcher

In questi giorni mi sono concesso un po’ di completo relax, e nel relax ho cominciato a smaltire un po’ di arretrati di Pocket, arrivando alla review dell’iPhone X su Daring Fireball. No, non ho comprato un iPhone X, no, non lo farò, ma trovo il modo di scrivere di John veramente scorrevole e stimolante; la chicca che ho trovato a poca distanza dall’inizio è lo Switcher, di cui non sapevo assolutamente nulla.

“Excuse me,” he told us, as he pressed a key combination on his keyboard, his monitor screen instantly changing to a different program. He talked on the phone for a minute or two, occasionally typing, before he finished the conversation and pressed a key combination to switch back to his Thunderscan notes.

Oggi, nel 2018, con un colpo di Alt-Tab possiamo passare in un secondo dal browser alla suite ufficio, dal terminale all’editor di testo. Possiamo cominciare a scrivere alla nostra fiamma in mezzo secondo. Possiamo far finta di lavorare mentre guardiamo Facebook1.

Andy Hertzfeld ha scritto il primo window switcher per Mac, in un’epoca in cui scrivere questo tipo di applicazioni era veramente, veramente difficile. Personalmente sono molto affezionato al mio Alt-Tab sin dai primi anni con Linux, e leggere la storia di come è stata concepita questa funzionalità devo dire che è stato emozionante.

A conti fatti, per parecchi nerd come me, Hertzfeld è responsabile di una parte del computing desktop come lo conosciamo oggi. Switcher è stato integrato successivamente in MacOS Classic, continuando ad evolvere fino ad OS X con l’implementazione “attuale”. Nel frattempo anche Windows e Linux hanno implementato i loro window switcher: tutto per via di questa storia, che trovo straordinariamente affascinante.

  1. Se un mio datore di lavoro presente, passato o futuro dovesse inciampare in questo post, ci tengo a specificare che è solo un esempio dei molti possibili. 

Elixir per idioti /2, tipi e operazioni sui tipi

Visto che abbiamo imparato come configurare Elixir sulla nostra macchina, un po’ di esperimenti e un approccio di base.

I tipi sono interi, numeri (in virgola mobile), booleani, atomi1, e stringhe.

Possiamo giochicchiarci in iex:

iex(1)> 1 + 2
3
iex(2)> "hello" <> "world"
"helloworld"
iex(3)> false || true
true
iex(4)> !true
false
iex(5)> !false
true
iex(6)> true == true
true
iex(7)> 2 == 2
true
iex(8)> 2 == "2"
false
iex(9)> 2 == 2.0
true
iex(10)> 2 === 2.0
false

Cose che possiamo notare sin da subito: le operazioni con tipi discordanti non funzionano, al contrario per esempio di JavaScript dove possiamo sommare stringhe e numeri indistintamente ottenendo una concatenazione (per esempio, grazie al casting implicito “molto libertino”); oltre questo, la comparazione con l’operatore == è debolmente tipizzata, ma i tipi compatibili tra loro sono molti meno. 2 è diverso da "2" ma è uguale a 2.0, che è in virgola mobile.

L’uguaglianza con il numero in virgola mobile viene falsificata da una comparazione “strict”, ovvero con triplo uguale, che fa anche un check del tipo.

I tipi li considero sempre la parte noiosa, ma vanno studiati; tra le cose divertenti invece abbiamo l’interpolazione di stringhe, che è abbastanza utile:

iex(15)> lang = "Elixir"
"Elixir"
iex(16)> "I'm studying #{lang}"
"I'm studying Elixir"

Stiamo carburando? Stiamo carburando! Mancano ancora un po’ di basi, tra cui le strutture dati fondamentali per non scrivere cose nonsense. Le vedremo in seguito.

Vai alla parte 1

Vai alla parte 3

  1. Gli atomi sono una figata, chi conosce la programmazione funzionale penso li conosca bene. Per chi non la conosce, sono delle stringhe “on steroids”; ne parleremo più avanti in ogni caso. 

Member of

Previous Random Next