Nel precedente post ho ripercorso le motivazioni che hanno portato a WinRT.
Uno dei requisiti fondamentali di WinRT è di permettere una migliore interazione tra linguaggi differenti, sia nativi che managed. Abbiamo anche già visto che per avere un'interoperabilità pulita e semplice sia necessario un vero e proprio runtime che esponga le funzionalità in modo object oriented.
L'interoperabilità tra i linguaggi e WinRT viene appianata dalle "projections" che risolvono due problemi:
- Usare WinRT dai linguaggi in modo semplice e performante
- rendere WinRT disponibile ai linguaggi come fosse una libreria di quel linguaggio e quindi utilizzabile in modo "naturale"
Il primo passo è stato perciò quello di stabilire un type system.
I tipi numerici sono supportati nelle versioni con e senza segno (interi e floating point). Il problema maggiore nasce per javascript che, stando alle specifiche ECMA, supporta un solo tipo numerico (il tipo floating point delle specifiche IEEE-754) sia per interi che per float, cosa che gli impedisce di gestire gli interi oltre i 53 bit di precisione. Il kernel di Windows usa i tipi a 64 bit (anche nella versione a 32 bit) per certe funzionalità come la dimensione dei file, gli offset, etc.
Esiste un nuovo tipo String la cui rappresentazione binaria permette di evitare il marshalling con le wstring di C++ o del Framework.NET. La nuova String è immutabile come nel Framework.NET ma invece di essere un reference type in WinRT è un value type come accade per wstring e quindi non-nullabile. Questo permette di appianare la differenza tra i vari linguaggi. Per costruire stringhe i developer C++ useranno wstring o wstringstream, mentre quelli VB/C# useranno come sempre StringBuilder.
Reference type. WinRT descrive il layout degli oggetti usando le interfacce, conseguentemente sono reference type tutti gli oggetti che implementano interfacce. Perciò durante una chiamata i parametri che sono oggetti sono passati by reference mentre tutto il resto sono by value. Inoltre i parametri sono passati come [in] o [out] e mai in [in, out].
Value type. Rispetto alla definizione dei reference type, i value type sono "il resto". Gli array sono value type (al contrario del Framework.NET) e le structure che non possono contenere puntatori/reference eliminando così il problema del costo e di come implementare la copia (deep vs shallow copy).
Tra i vari type definiti nel namespace "Platform" spiccano Vector e Map, analoghi a collection e dictionary del Framework.NET. Da notare che Vector<T> è implementa IObservableVector<T> e quindi supporta nativamente le notifiche sulle modifiche.
Ovviamente ci sono boolean, enum e molti altri tipi di base come Object, Type e Guid, ma su cui non ho trovato nulla di diverso da ciò che mi attendevo.
Per rendere disponibile WinRT ai linguaggi in modo naturale, le projection modificano anche il casing della libreria. Le convenzioni di javascript per esempio sono di usare camelCase per properietà e metodi, il PascalCase per i type e lowercase per gli eventi. WinRT invece segue sempre le convenzioni del Framework.NET, cioè il PascalCase. La projection modifica i nomi delle librerie seguendo le convenzioni del linguaggio "projected".
È chiaro che ogni linguaggio presenta comunque particolarità che non possono essere ignorate. Questo è stato un problema anche durante il design del Framework.NET (vedi attributo CLSCompliant) e continua ad esserlo in WinRT.
Piuttosto il fatto di aver definito il modo in cui i linguaggi sono interfacciati a WinRT apre l'interessantissimo scenario dei linguaggi di terze parti. A questo punto sembra un passo ovvio per Java, Python, Ruby, D, Delphi e chissà quanti altri.