We Can’t Stop Here! This Is Bat Country!!

Scusate per il messaggio inutile, ma l’ultimo upgrade di WordPress alla versione 2.6 sembra avermi portato a 2 o 3 problemini sparsi qua e là per cui mi tocca fare qualche prova di troppo. Per renderlo un po’ meno inutile posso dirvi che mi sono finalmente deciso a installare Debian sul mio NSLU2 (per l’occasione ho scelto la più aggiornata Lenny, sono temerario). Il device in oggetto è ufficialmente supportato con alcuni pacchetti mirati specificatamente ad esso ed è un’altra vita rispetto a SlugOS/BE. Nonostante quest’ultima sia leggermente più ottimizzata poiché specificatamente creata per uso su sistemi embedded, con Debian il sistema sembra comportarsi comunque piuttosto bene soprattutto dopo qualche tweak. More to come, ora devo sistemare qualche pezzo di blog…

Ancora su lambda e closure in PHP

Anche se a pochi giorni di distanza, ho pensato di tornare a parlare di funzioni lambda e closure in PHP approfittando di un nuovo aggiornamento della RFC (con relativa patch che implementa quanto descritto) in cui sono state finalizzate alcune idee e sono stati introdotti alcuni nuovi concetti.

Prima di tutto è stata presa una decisione per quanto riguarda la sintassi dichiarativa, infatti precedentemente erano state formulate due possibilità. La prima prevedeva la cattura delle variabili esterne alla chiusura tramite una nuova keyword creata ad hoc, lexical:

$lambda = function($arg1, $arg2) { lexical $reference, &$valueByRef; // ... };

La seconda, quella che è stata effettivamente scelta, prevede invece il riutilizzo della keyword già esistente use:

$lambda = function($arg1, $arg2) use ($reference, &$valueByRef) { // ... };

Qualcuno preferiva la prima opzione e personalmente ero dello stesso avviso, ma alla fine la scelta è stata dettata dall’intenzione di raggiungere un compromesso in maniera tale da ottenere le stesse funzionalità mantenendo la consistenza con l’attuale semantica di PHP e senza intaccare la retrocompatibilità.

La prima estensione nella RFC riguarda invece l’utilizzo della keyword static per stabilire se importare o meno $this all’interno di una chiusura definita all’interno del metodo di una classe. Non effettuare l’importazione di $this all’interno di una chiusura quando non necessario permette di ottenere un risparmio non solo in termini di velocità d’esecuzione, anche si tratta di differenze veramente minimali, ma anche e soprattutto di memoria, evitando che delle long-lived closure possano tenere in vita inutilmente le istanze delle classi in cui esse sono state create. La chiusura che cattura $this infatti impedisce che il refcount interno per l’oggetto che referenzia possa arrivare a 0 e ciò ne comporta l’esclusione dal processo automatico di raccolta delle risorse che viene effettuato dal garbage collector. Vediamo un esempio pratico con tanto di risultato:

class NRK { private $_whoAmI = __CLASS__; public function foo() { $method = __METHOD__; return function() use ($method) { return sprintf("created in %s (w/ \$this):\n%s", $method, print_r($this, true) ?: 'null' ); }; } public function bar() { $method = __METHOD__; return static function() use ($method) { return sprintf("created in %s (w/o \$this):\n%s", $method, print_r($this, true) ?: 'null' ); }; } } $nrk = new NRK(); $fun1 = $nrk->foo(); $fun2 = $nrk->bar(); echo $fun1(), "\n", $fun2(); /* created in NRK::foo (w/ $this): NRK Object ( [_whoAmI:NRK:private] => NRK ) created in NRK::bar (w/o $this): null */

In realtà trovo che sarebbe molto più comodo e pulito avere $this importata in automatico nel caso essa venga esplicitamente richiamata nel corpo della closure, per il compilatore non sarebbe difficile accorgersene ed agire di conseguenza, ad ogni modo non mi piace l’uso della keyword static dal momento che rende ancora più verbosa la definizione di una chiusura.

Proseguendo con le nuove funzionalità, nell’ottica di una maggiore integrazione con PHP sono state estese le classi ReflectionMethod e ReflectionFunction implementando il metodo getClosure() che permette di ottenere una funzione lambda generata dinamicamente partendo da una funzione o da un metodo di istanza/classe:

class NRK { public function instanceMeth() { return __METHOD__; } public static function staticMeth() { return __METHOD__; } public static function methWithArgs($a, $b) { return $a + $b; } } $instance = new NRK(); $class = new ReflectionClass('NRK'); $fun1 = $class->getMethod('instanceMeth')->getClosure($instance); $fun2 = $class->getMethod('staticMeth')->getClosure(); $fun3 = $class->getMethod('methWithArgs')->getClosure(); echo $fun1(), "\n", $fun2(), "\n", $fun3(5, 3); /* NRK::instanceMeth NRK::staticMeth 8 */

Per finire, un’altra novità ispirata dall’implementazione dell’oggetto Closure riguarda la generalizzazione del concetto di oggetto invocabile attraverso l’implementazione di un nuovo metodo magico, __invoke(). Un esempio vale più di mille parole:

class CallableObject { public function __invoke () { return 'Guess what?'; } } $callable = new CallableObject(); $notCallable = new stdClass(); echo '$callable is ', is_callable($callable) ? '' : 'not ', "a callable object\n"; echo '$notCallable is ', is_callable($notCallable) ? '' : 'not ', "a callable object\n"; echo $callable(); echo $notCallable(); /* $callable is a callable object $notCallable is not a callable object Guess what? Fatal error: Function name must be a string in [...] */

Tirando le somme lo stato dell’implementazione di lambda e closure in PHP sembrerebbe essere in uno stato particolarmente avanzato al punto tale che lo stesso Andi Gutmans su php.internals ha chiesto, soprattutto ai release manager, di pensare se sia effettivamente possibile includere tutto questo già in PHP 5.3. In effetti PHP 5.3 sarà già ricco di novità di per sè (namespace e collaterali, LSB, __callStatic, etc) quindi l’introduzione di un’altra nuova feature è da valutare bene, tuttavia vista la buona salute della proposta e dei lavori per implementarla sarebbe un peccato dover aspettare un altro anno o più. Intanto però c’è anche chi si chiede: ma alla fine le novità di PHP 6 saranno rappresentate solo dal supporto per Unicode?

Lambda e closure in PHP 5.3? Forse sì, forse no, ma intanto proviamo.

Negli ultimi giorni sulla mailing list di sviluppo di PHP si sta discutendo sulla possibilità di estendere il linguaggio in maniera tale da introdurre i concetti di funzioni lambda e di closure tanto cari a molti linguaggi dinamici come Ruby, Python, JavaScript, etc. In realtà si potrebbe quasi considerare come un ritorno di fiamma, già in passato ci furono discussioni simili anche se poco convinte e poco convincenti, tuttavia questa volta si intravede la possibilità di sfociare in una decisione furba nonostante non ci sia particolare interesse nell’implementazione da parte di alcuni dei core-dev (tanto per cambiare). Attualmente il tutto ruota intorno a una RFC che, oltre a mettere in evidenza alcuni scenari sull’utilizzo di funzioni lambda e chiusure e riportare i dettagli implementativi nell’engine di Zend, allega alcune patch con alcune piccole varianti sul tema da applicare ai sorgenti nei rami di sviluppo di PHP 5.3 e PHP 6.0 per poter toccare con mano quanto si sta discutendo.

$fun = function($name = 'guy') { echo "Hi $name!"; }; printf("Tipo: %s\n", get_class($fun)); // Type: Closure printf("Callable: %s\n", is_callable($fun)); // Callable: 1

Come possiamo notare, è stato implementato un nuovo tipo in ZE denominato Closure. Closure risulta essere invocabile, alla stessa stregua di funzioni e metodi:

echo $fun(); // Hi guy! echo $fun('NRK'); // Hi NRK!

Il primo pensiero va a questo punto a tutte quelle funzioni in PHP che accettano delle callback ma in cui comodità ed espressività vengono pesantemente minate dall’attuale modus operandi del linguaggio che prevede due opzioni:

  • definire una funzione tradizionale da usare come argomento callback ma sotto forma di stringa (il nome della funzione stessa), dando quindi origine a potenziali bugs galore.
  • creare una funzione a runtime usando create_function, opzione che oltre a risultare poco elegante alla vista rischia di introdurre un’altra buona dose di problemi in termini di manutenibilità del codice.

Ecco quindi un confronto tra come è possibile scrivere codice oggi e la possibilità di sviluppare la stessa soluzione attraverso l’utilizzo delle funzioni lambda:

$array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); /* senza funzioni lambda */ function reducer($a, $b) { return $a * $b; } $res = array_reduce($array, 'reducer', 1); // 3628800 /* senza funzioni lambda */ $res = array_reduce($array, create_function('$a, $b', 'return $a * $b;'), 1); // 3628800 /* con funzion lambda - versione "lunga" */ $reducer = function($a, $b) { return $a * $b; }; $res = array_reduce($array, $reducer, 1); // 3628800 /* con funzion lambda - versione "breve" */ $res = array_reduce($array, function($a, $b) { return $a * $b; }, 1); // 3628800

Il fatto che l’oggetto Closure sia a tutti gli effetti visibile in userland permette anche di sfruttare l’hinting dei tipi nel caso volessimo limitare a questo tipo di oggetto alcuni parametri delle nostre funzioni:

function iterate($array, Closure $fun) { foreach ($array as $element) $fun($element); } iterate($array, 'function'); // genera un Catchable Fatal Error, Argument 2 passed to // iterate() must be an instance of Closure, string given

Essendo Closure una vera e propria classe (che, per la cronaca, attualmente espone solo un metodo __toString() seppur vuoto) potrebbe implementare in un ipotetico futuro diverse funzionalità interessanti e chissà, potrebbe anche essere serializzabile. Ad ogni modo, dopo le funzioni lambda passiamo a vedere le closure:

$array = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); $sum = 0; $fun = function($element) { lexical &$sum; // ... $sum += $element; }; array_walk($array, $fun); echo $sum; // 55

Possiamo notare l’introduzione della keyword lexical (c’è anche la variante use a seconda della patch che si decide di utilizzare) che ci permette di catturare i riferimenti alle variabili esterne al corpo della chiusura. L’introduzione di lexical è dovuta al fatto che con questa implementazione non viene catturato tutto l’ambiente lessicale in cui viene creata la chiusura, come accade invece in altri linguaggi, per motivi legati principalmente alle regole di scope di PHP. Usando lexical possiamo pertanto decidere quali variabili catturare, ma è da notare che attualmente per i tipi numerici o stringa, che per default in PHP sono passati per valore, è necessario creare manualmente un riferimento anteponendo l’ampersand alla variabile catturata, come da esempio. Tecnicamente la cattura per riferimento dovrebbe essere di default anche per questi tipi e lo stesso creatore della patch è del medesimo avviso, tanto più che il terribile global si comporta nello stesso modo creando sempre riferimenti.

In linea di massima l’introduzione di funzioni lambda e closure in PHP sarebbe interessante e in certe situazioni renderebbe la scrittura dei programmi un po’ meno arrabattata con la possibilità di ottenere codice molto più facilmente generalizzabile e più verificabile/manutenibile. Provare è abbastanza facile: basta avere un ambiente configurato per compilare PHP, scaricare i sorgenti di PHP 5.3 o 6.0 dal repository CVS (sì, usano ancora CVS…), applicare una delle patch disponibili, compilare e installare.

Questo blog supporta OpenID

Logo di OpenIDFinalmente ieri sera ho attivato su questo blog il supporto per OpenID nei commenti dopo aver tentato l’impresa nei mesi precedenti provando alcuni plugin i quali, tuttavia, non hanno mai dato risultati molto incoraggianti. Questa volta ho usato WP-OpenID e l’integrazione con il blog e il suo tema si è dimostrata rapida e indolore. L’unico neo, a cui devo ancora dare una spiegazione ma attendo di avere due minuti in più a disposizione per approfondire, riguarda la mancata o errata gestione della delegazione: per esempio il mio OpenID è http://clorophilla.net con delegazione a myOpenID come provider di identità, però quando tento di usarlo nei commenti del mio blog viene generato un errore. Ad ogni modo si tratta di un buon passo in avanti considerato che era da tempo che volevo attivare la possibilità di commentare sfruttando il proprio OpenID, per sistemare i glitch c’è tempo.

IronRuby sempre più vicino a Ruby on Rails

Se non è in grado di far girare Ruby on Rails, allora non è Ruby… più o meno con queste parole John Lam, agli inizi dello sviluppo di IronRuby, aveva sottolineato la volontà di ottenere un’implementazione del linguaggio che fosse il più fedele possibile all’MRI (l’interprete originale di Matz). Oggi, con questo suo tweet, arriva la prima dimostrazione pratica di come questo obiettivo sia ormai sempre più vicino. Ovviamente manca ancora parecchio lavoro per completare IronRuby e attualmente il team è dedicato interamente a implementare e sistemare tutte le parti necessarie a poter effettuare l’hosting di una semplice applicazione RoR giusto in tempo per la RailsConf 2008 che avrà inizio tra pochi giorni, ma il ritmo sembra ormai molto buono. E’ interessante far notare che negli ultimi due mesi il lavoro del team di IronRuby si è fatto molto più trasparente in seguito a una forte critica sviluppatasi direttamente sulla mailing list, in cui si faceva notare come l’assenza di aggiornamenti sullo stato dei lavori e i commit in SVN abbastanza rari rendevano il lavoro di contribuzione e di testing molto difficile. La discussione ha generato un dialogo che ha portato a commit decisamente più frequenti, post dei diff sulla mailing list e review del codice e dei nuovi sviluppi… e la comunità che si sta formando intorno ad IronRuby ha apprezzato. Personalmente in queste ultime due settimane di silenzio sul blog ho avuto modo, tra le varie attività, di approfondire più seriamente gli internals di IronRuby provando a implementare qualche funzionalità mancante e devo ammettere che il suo codice e la struttura generale del progetto si sono dimostrati dannatamente ottimi e relativamente facili da capire nonostante non sia ancora esistente documentazione pubblica in merito (sarebbe stata inutile dal momento che il core ha cominciato a stabilizzarsi solo di recente). Se nel frattempo io mi sono divertito con metodi semplici come Kernel#rand e Kernel#srand per poi passare a Kernel#system con relativa classe Process::Status per cominciare a prendere familiarità con il progetto, qualcuno si è spinto ben oltre iniziando a ricreare un’implementazione di Shoes su IronRuby basandosi sulle API .NET di Windows Forms… potremmo chiamarlo IronShoes? Insomma ad oggi sono fortemente ottimista riguardo al futuro di IronRuby soprattutto visti gli ultimi sviluppi. Sono ottimista anche per la situazione di Ruby in generale perché stanno arrivando segnali molto interessanti dalla comunità, ma preferisco parlare di questo in un post successivo.

Mi mancava giusto Twitter

Non ho mai visto di buon occhio Twitter, sono sincero. Non ho mai capito per quale motivo dovrei sbandierare a chissà chi quello che sto facendo, costantemente, soprattutto nell’inutilità di frasi tipo "ehi sto uscendo di casa" oppure "sto andando a letto". Oh wow, chissenefrega. Probabilmente quelle poche volte che ho provato a curiosare mi sono sempre trovato di fronte a esempi sbagliati (soggettivamente parlando, sia chiaro), forse ho anche sofferto un po’ di sindrome da preconcetto, ma giungendo al sodo la mia impressione è sempre stata quella… tanto è vero che ho aperto un account su Twitter. Coerenza, questa sconosciuta!

No non sono impazzito, non solo perché un pazzo non può impazzire ma perché mi sono accorto di recente che su Twitter oltre a poter intercettare segnalazioni rilevanti con tempi quasi da record possono nascere anche brevi ma interessanti discussioni tra developer e appassionati di tecnologia, un fatto se vogliamo abbastanza paradossale se pensiamo all’essenzialità della comunicazione che caratterizza questo strumento. Rapidità, in questo periodo per me è un aspetto rilevante e al tempo stesso vedo il mio tumblelog su Tumblr come uno strumento differente da Twitter non solo nelle modalità ma anche nello scopo. Per ora la mia scelta ha una connotazione puramente sperimentale, devo ancora entrare nell’ottica e devo iniziare a inserire un po’ di gente da seguire però nel frattempo ho scoperto twhirl, un ottimo client Twitter basato su Adobe AIR (Windows e Mac OS X, per cui devo cercare ancora qualcosa per Linux) carino a vedersi e ricco di funzionalità che rende la fruizione del servizio ancora più comoda e veloce. Vedremo come andrà a finire, fatico sempre a metabolizzare certi servizi o strumenti non essendo mai stato particolarmente convinto o attratto dalla tendenza al sociale-a-tutti-i-costi degli ultimi anni, però con il tumblelog ha funzionato per cui chissà…

ILX: il CIL di .NET esteso per l’interoperabilità con i linguaggi funzionali

Facendo un po’ di ricerche sparse sono incappato nell’ennesimo progetto interessante targato Microsoft Research: ILX. Alla base di questo progetto, che porta la firma di Don Syme (già ideatore nonché sviluppatore principale di F#), vi è l’idea di ampliare il CIL destinato a essere elaborato dal CLR con lo scopo di ottenere un linguaggio intermedio che, rispetto a quello attuale, supporti particolari estensioni espressamente mirate a un miglior supporto e a una maggiore integrazione dei linguaggi funzionali sulla piattaforma .NET. Curiosamente non si tratta di un’idea nuova ma i paper risalgono addirittura al 2001 e sono stati presentati a un workshop di quel periodo. Le estensioni proposte permettono di ottenere un supporto diretto per:

  • polimorfismo parametrico, il quale è stato poi effettivamente implementato a livello nativo quando sono stati introdotti i generics nel CLR (Syme è effettivamente uno dei padri dell’implementazione dei generics in .NET).
  • unioni discriminate, ovvero i variant record (o il tipo variant) che sono nativi in linguaggi come ML e derivati o Haskell mentre in linguaggi come Nemerle e F# sono implementati sotto forma di zucchero sintattico con traduzione nel tipico modello a oggetti da parte dei relativi compilatori.
  • funzione come oggetto (first-class function, da non confondersi con i delegate di C# anche se il concetto è in parte simile), closure e thunk (che sarebbe anche un passo in avanti per call/cc).

Qualcuno potrà pensare che in tutto questo tripudio di estensioni manchi all’appello qualche forma di supporto per le chiamate tail utili per la cosidetta tail recursion, in realtà non vi è nessuna dimenticanza poiché il CLR le ha sempre supportate nativamente anteponendo nell’IL il prefisso tail. alle istruzioni call, callvirt e calli (quest’ultimo link è locale poiché l’originale è recuperabile solo dalla cache di Google, ma prima che sparisca…).

Con queste estensioni sarebbe possibile offrire una base comune agli implementatori di linguaggi sulla piattaforma .NET permettendo loro di spostare la gestione di costrutti tipici in certi linguaggi verso la macchina virtuale piuttosto che delegandone a ogni singolo compilatore la traduzione negli altri costrutti supportati attualmente, potendo offrire a questo punto anche delle ottimizzazioni a basso livello nella macchina virtuale stessa. Da un certo punto di vista è la stessa idea di base, anche se a un livello molto differente, che ha portato alla nascita del DLR sotto forma di libreria.

Per avere una visione completa di questo progetto vi riporto il link al paper completo in PDF presentato al BABEL’01 (si è dimostrata una lettura piuttosto interessante) e il link diretto alla reference di ILX (purtroppo solo in formato DOC). Per la cronaca, nella pagina dedicata al BABEL’01 è possibile trovare molti altri documenti interessanti.

Prove tecniche di programmazione in Nemerle [1ª parte]

Ormai è da qualche mese che ho deciso di elevare F# a mio linguaggio dell’anno e gli darò sicuramente spazio su questo blog nel prossimo futuro, tuttavia nell’ultimo periodo sono stato distratto da Nemerle, un linguaggio compilato a tipizzazione statica costruito anch’esso sulla piattaforma .NET e che unisce contemporaneamente caratteristiche tipiche dei linguaggi funzionali, imperativi e orientati agli oggetti. Nonostante a parole F# e Nemerle possano sembrare linguaggi equivalenti, nella realtà tra i due vi sono differenze sostanziali tanto che quest’ultimo ha:

  • un approccio maggiormente OO-centrico
  • un sistema di meta-programmazione particolarmente potente attraverso l’utilizzo di macro à la Lisp che lo rende particolarmente estendibile

In effetti la meta-programmazione è un elemento chiave di Nemerle tanto che il core stesso vi si basa pesantemente, vi basti pensare che costrutti base del linguaggio come if, for, foreach e while sono definiti in realtà attraverso delle macro:

macro @if (cond, e1, e2) syntax ("if", "(", cond, ")", e1, Optional (";"), "else", e2) { <[ match ($cond) { | true => $e1 | _ => $e2 } ]> }

Dal codice è possibile notare come la macro if sia implementata utilizzando internamente una caratteristica tipica di molti linguaggi funzionali definita pattern matching. Curiosamente l’applicazione del pattern matching in Nemerle può essere sfruttata direttamente in altri costrutti come foreach omettendo la keyword match:

1 def range = $[0 .. 5]; 2 3 foreach (num in range) { 4 | num when num % 2 == 0 => print($"$num: even | ") 5 | _ => print($"$num: odd | ") 6 } 7 8 // OUTPUT: 9 // 0: even | 1: odd | 2: even | 3: odd | 4: even | 5: odd |

 

  • riga 1: in questa riga istanziamo un range, ma è da notare che esistono anche le list comprehension tipiche di Python (anche se con una sintassi un po’ più criptica).
  • riga 4: il primo pattern prevede che il numero sia pari, se il valore non combacia con il pattern allora si passa a quello successivo.
  • riga 5: l’utilizzo di _ nel pattern matching equivale a un catch all (una sorta di clausola default in uno statement switch) in cui vi si entra se non si verifica alcun match con i pattern specificati in precedenza.

Dall’esempio si può notare inoltre come non sia stato specificato alcuni tipo per gli oggetti, questo grazie al sistema di type inference che permette al compilatore di dedurre i tipi in fase di compilazione. Anche il costrutto try … catch … finally è stato leggermente rivisto rispetto al solito per uniformarsi alla filosofia del linguaggio:

def (a, b) = (12, 0); try { def n = a / b; } catch { | e is DivideByZeroException => print($"You got to have some guts to divide $a by $b!"); | e is Exception => { // ... } } // OUTPUT: // You got to have some guts to divide 12 by 0!

E’ evidente quindi come il pattern matching possa essere sfruttato in svariati ambiti che non si limitano a semplici stringhe o numeri, infatti può essere applicato anche nel controllo di tipi (attraverso is, come nell’esempio di try … catch), su enum o variants (un altro tipo che arriva direttamente dal mondo funzionale), su tuple e liste, su proprietà o campi di un’istanza di classe. Un’altra applicazione particolare del pattern matching si può trovare nelle espressioni regolari:

foreach (str in ["ciao", "aiuola", "casa", "44 gatti"]) { regexp match (str) { | "^a.*a$" => printf("\"%s\" inizia e termina con la lettera \"a\"\n", str); | @"^(?<num : int>\d+).+" => printf("\"%s\" inizia con il numero %d\n", str, num); | _ => printf("Nessun match per \"%s\"\n", str); } } /* OUTPUT: Nessun match per "ciao" "aiuola" inizia e termina con la lettera "a" Nessun match per "casa" "44 gatti" inizia con il numero 44 */

Come accennato in precedenza esiste un tipo Variant (simile al tipo datatype di ML, a cui Nemerle in parte si ispira) il quale, almeno a prima vista, potrebbe sembrare ridondante con il tipo Enum derivato da C# in quanto apparentemente simili ma che in realtà risulta essere molto più potente e flessibile. Un esempio, preso dal sito di Nemerle ma leggermente espanso, vale più di mille parole:

1 variant RgbColor { 2 | Red 3 | Yellow 4 | Green 5 | Different { 6 red : float; 7 green : float; 8 blue : float; 9 } 10 } 11 12 def colors = [ RgbColor.Red, 13 RgbColor.Green, 14 RgbColor.Different(0, 127, 255), 15 RgbColor.Different(blue = 255, red = 0, green = 127) ]; 16 17 18 def string_of_color(color : RgbColor) : string { 19 | RgbColor.Red => "red" 20 | RgbColor.Yellow => "yellow" 21 | RgbColor.Green => "green" 22 | RgbColor.Different(r, g, b) => $"rgb($r, $g, $b)" 23 } 24 25 foreach (color in colors) printf("%s\n", string_of_color(color)); 26 27 /* OUTPUT: 28 red 29 green 30 rgb(0, 127, 255) 31 rgb(0, 127, 255) 32 */

Possiamo notare alcuni particolari:

  • riga 5: il tipo variant permette di creare nuove opzioni partendo da informazioni aggiuntive, in questo caso un colore non contemplato dalle opzioni del tipo variant RgbColor può essere ugualmente espresso sotto forma di valori RGB
  • riga 14-15: il costruttore per l’opzione RgbColor.Different può essere invocato passando ad esso i valori degli argomenti con lo stesso ordine della definizione dell’opzione stessa oppure sfruttando i named parameter supportati da Nemerle
  • riga 18-19: come nel caso precedente di foreach, possiamo omettere match anche nello sviluppo di funzioni se esso si trova all’inizio del corpo della funzione
  • riga 22: possiamo effettuare il binding di variabili ai campi di un’opzione di un tipo variant nello stesso modo in cui abbiamo invocato il costruttore dell’opzione stessa, ovvero seguendo l’ordine della definizione dei campi (come nell’esempio) oppure sfruttando i named parameters, con cui avremmo potuto scrivere:

    | RgbColor.Different(red = r, blue = b, green = g) => $"rgb($r, $g, $b)"

Questi sono solo alcuni esempi di programmazione in Nemerle per cominciare a comprendere la filosofia del linguaggio, ne seguiranno ulteriori in altri messaggi ma prima ci tengo a esprimere alcune considerazioni. Nemerle rimane un progetto portato avanti da un gruppo di sviluppatori dell’università di Wrocław senza fondi o supporto esterni, al contrario di F# che è nato in seno al progetto Microsoft Research ed diventato recentemente parte integrante della piattaforma .NET. Questo significa che, nonostante la solidità del design del linguaggio e la sua implementazione generalmente stabile, non è esente da problemi o da qualche mancanza sparsa (personalmente una delle maggiori, anche se by-design, risiede nel fatto che non è possibile implementare iteratori in funzioni locali usando yield). Inoltre all’apparenza il progetto può sembrare poco supportato dai suoi sviluppatori e al limite dell’abbandono, ma in realtà viene portato avanti e attualmente uno degli obiettivi è il rilascio ogni 1~3 mesi di nuove CTP dell’attuale versione instabile 0.9.4. Alla fine dei conti si tratta comunque di un linguaggio abbastanza interessante per certe sue caratteristiche quindi vale la pena giocarci un po’. Tra l’altro è possibile usare Nemerle anche in Linux dal momento che si integra molto bene con Mono, non per niente tutte le mie prove sono state eseguite su una Xubuntu 8.10 con Nemerle 0.9.3 e Mono 1.2.6 (come da repository ufficiali di Hardy Heron) usando SciTE come editor, anche se si tratta di un linguaggio supportato da MonoDevelop.

Finalmente…

… un po’ di calma dopo un mese di lavoro intenso e frenetico in ufficio, programmato meticolosamente su un calendario disegnato su una lavagna a muro e culminato in 22 ore di lavoro su 48 tra domenica e lunedì scorsi. No, non per mancanza di organizzazione o pianificazioni sbagliate, semplicemente lo richiedeva l’evento e fino all’ultimo ci sono state diverse sòle altrui da sistemare. Poco male dal momento che, come previsto dato che siamo super-fighi (ok ok, passatemela e fate finta di niente), è andato tutto bene. Recupererò qualche arretrato del blog con un sunto casuale, approfondirò più avanti alcuni di questi punti:

  • Settimana scorsa mi è arrivato Expert F# e ieri sera gli ho dato una rapida occhiata: come libro mi sembra ben fatto e tutti gli esempi in codice più corposi sono scaricabili dal sito ufficiale. Non mi è ben chiaro però il motivo per cui, in attesa di iniziare a leggerlo seriamente, mi sono messo a fare esperimenti con Nemerle. Bah, misteri della psiche, nel dubbio ho acquistato anche The Ruby Programming Language visto che è aggiornato a Ruby 1.9 e che avevo voglia di un altro libro sull’argomento.
  • Qualche settimana fa ho acquistato una board Arduino, la versione Diecimila per la precisione, dopo averne scoperto il progetto qualche mese prima: tutta colpa sua che me lo ha ricordato indirettamente :-P In realtà non ho avuto tempo di giocarci molto visti gli impegni, inoltre per me è difficoltoso poiché di elettronica ci capisco poco (uno degli obiettivi è cercare di approfondire l’argomento), per ora sono andato sul classico cercando di pilotare un LCD 2×16 senza però usare nessuna delle librerie già a disposizione. Ho provato anche a configurare RAD su Mac OS X senza però riuscirci, anche se sospetto che il problema sia legato alla versione dell’ambiente di sviluppo di Arduino poiché ho installato l’ultima mentre ad oggi nella documentazione di RAD viene richiesta esplicitamente la versione precedente. More to come…
  • Ho installato il service pack 1 di Windows Vista e finalmente è sparito il lag che caratterizzava alcune operazioni, soprattutto in Explorer (non IE). Hanno sistemato anche le prestazioni del trasferimento di file via rete, prima raggiungevo la ridicola velocità di 11.5 MB/s ad andar bene su una rete gigabit trasferendo file tra 700 MB e 1 GB, ora raggiungo i 37 MB/s con gli stessi file prelevati dallo stesso computer e con le stesse configurazioni… a parte SP1 lato Vista, appunto. Non ho notato cambiamenti particolari sulla stabilità delle applicazioni e del sistema, del resto non ho più avuto problemi in questo senso da qualche mese a questa parte.
  • Da sempre sono fedele alla mia vetusta versione di ACDSee 2.43 risalente al 2000: velocissimo, leggerissimo e ha quasi tutto quello che mi serve. Non ho mai nemmeno considerato l’upgrade dal momento che le versioni immediatamente successive erano orrende e lente e quelle attuali non so nemmeno cosa facciano. L’altro giorno però ho scoperto che XnView nelle ultime versioni è migliorato parecchio rispetto a quando lo provai qualche anno fa e in più, oltre a essere free per uso non commerciale, ha un sistema di riconoscimento delle immagini simili/duplicate che parrebbe dare risultati interessanti. Quasi quasi provo a installarlo su Vista dove non ho nessun visualizzatore a parte quello di default del sistema.
  • Le HP XW8600 sono workstation impressionanti, soprattutto quando si tratta della versione dual Xeon quad-core. Ovviamente costano una cifra abnorme, ma del resto sembrerebbero valere il loro prezzo che probabilmente è stato deciso al chilogrammo visto che pesa 28 Kg a pieno carico. Negli ultimi giorni abbiamo avuto solo l’imbarazzo della scelta nel pensare a come metterle sotto stress al lavoro, non fanno una piega.
  • Il mese scorso ero alla ricerca di un nuovo set di auricolari per sostituire un paio di Sennheiser che, dopo 7 anni di onorato servizio nelle situazioni più disparate, ormai non ce la facevano proprio più. Per una clamorosa botta di culo sono riuscito a comprare un paio di AKG K 324 P bianchi a soli 39,90€ grazie a un’offerta scoperta per caso su Bow.it (leggasi: dovevo comprare altro quando ho visto scritto ultimo pezzo offerta speciale, inoltre la possibilità di ritirare in un BowPoint vicino all’ufficio risparmiando quindi le spese di spedizione ha contribuito ulteriormente). Solitamente lo stesso modello di auricolari si trova in negozi online tra i 50€ e i 55€ a cui occorre aggiungere le spese di spedizione, mentre in negozi normali li ho visti anche a 60€. Per essere auricolari suonano decisamente bene, posso ritenermi piuttosto soddisfatto.
  • DHL comincia a perdere colpi. Un pacco che aspettavo, ma che fortunatamente non era assolutamente urgente, è rimasto fermo in dogana per 1 settimana senza che io sapessi nulla, l’ho scoperto per caso andando sul sito e inserendo il codice della spedizione per fare il tracking dopo aver cominciato a nutrire qualche sospetto. Alla fine si aspettavano che io chiamassi in dogana per fornire il mio codice fiscale, cosa che normalmente hanno sempre fatto loro chiamandomi al cellulare per ottenere le informazioni necessarie allo sdoganamento. Il primo intoppo dopo anni di utilizzo… c’è sempre una prima volta, speriamo che rimanga l’unica però.