Ho finalmente iniziato a programmare un po’ in Erlang, in vista di quando dovrò iniziare a scrivere codice seriamente per la tesi (di cui parlerò più avanti, ora siamo parecchio agli inizi), ed oggi ho fatto un test estremamente semplice per giocare un po’ con il codice mobile.
Premesso infatti che Erlang favorisce il codice distribuito e la comunicazione tra nodi e processi remoti, mi sono chiesto se era possibile far muovere non solo dati (quindi variabili, anche se forse il termine variabile in questo contesto non è del tutto adatto, dato che sono immutabili), ma anche codice vero e proprio, in particolare funzioni e closure. E la risposta, naturalmente (e sorprendentemente), è stata: sì.
Il modulo qui sopra, dal comportamento piuttosto scontato, esporta un’unica funzione che riceve due parametri: una funzione (o meglio, una fun) F ed un valore Value, e non fa altro che invocare la prima passando il secondo; se F non è una funzione, il programma va democraticamente in crash, altrimenti ritorna il risultato di F (Erlang non richiede alcuna parola chiave return).
Questo modulo, debitamente compilato, è stato copiato in due computer diversi, che ho chiamato big e little, principalmente perchè il primo è il notebook ed il secondo è il netbook 🙂
Questa è la console del notebook: assegnato un nome di rete completo al nodo ed un cookie (e segato il firewall, forse ho sbagliato ad aprire la porta giusta per far comunicare Erlang), ho lanciato l’interprete e l’ho lasciato lì: il codice visto sopra non ha bisogno, infatti di essere in alcun modo avviato (ho anche creato una versione server, lievemente più complessa, ma il risultato è lo stesso anche con 2 righe 2 di codice), basta assicurarsi che l’interprete sappia dove trovare il file compilato, se ne avrà bisogno (ovvero se mai qualcuno dovesse richiedere una delle sue funzioni): nel caso più semplice basta lanciare l’interprete erl dalla cartella dove si trova tale file.
E qui, sul nodo little, avviene il bello: anche qui è necessario assegnare un nome di rete e lo stesso cookie di cui sopra (e lanciare l’interprete sempre dalla directory contente il file compilato, debitamente copiato dal primo nodo); a questo punto, ho dichiarato una funzione Double, che altro non fa che ricavare il quadrato del parametro, lanciarla in locale e successivamente in remoto, tramite la chiamata ad rpc:call(). Ed ha funzionato!
Cos’è successo
In pratica, nel secondo nodo è stata creata una fun, ovvero una funzione anonima assegnata ad una variabile; essendo la funzione appunto anonima, il suo codice non era a priori conosciuto dal primo nodo, dato che la sua implementazione (X*X) non era situata nel modulo presentato più sopra (che costituiva l’unico listato comune ai due nodi), bensì salvata in qualche modo direttamente nella variabile Double.
Quando tale variabile è stata inviata al nodo remoto, essa ha portato con sè tale implementazione, così che il nodo remoto è stato in grado di eseguirla e restituire al chiamante il risultato (4). Spettacolare!
Leave a Reply