È stata presentata la prima versione beta del linguaggio di programmazione Mojo 1.0, che segna la stabilizzazione del linguaggio e l'implementazione di tutte le funzionalità di base. Il rilascio è considerato quasi pronto per l'uso generalizzato. Il rilascio finale di Mojo 1.0 è atteso per l'inizio dell'autunno. L'uso di questa versione permetterà di iniziare a sviluppare progetti di grandi dimensioni, senza timori di cambiamenti che possano compromettere la compatibilità.
La piattaforma include componenti necessari per lo sviluppo di applicazioni nel linguaggio Mojo, tra cui un compilatore, runtime, un'interfaccia REPL interattiva per costruire e eseguire programmi, un debugger, un'estensione per l'editor di codice Visual Studio Code (VS Code) con supporto per il completamento automatico, il formattazione del codice e l'evidenziazione della sintassi, e un modulo per l'integrazione con Jupyter per costruire ed eseguire notebook Mojo. Il codice sorgente della libreria standard di Mojo è aperto sotto la licenza Apache 2.0 con eccezioni dal progetto LLVM, che consentono il mixing con codice sotto licenza GPLv2. Si prevede di aprire il codice sorgente del compilatore dopo il completamento della stabilizzazione dell'architettura interna.
Il linguaggio Mojo è sviluppato sotto la guida di Chris Lattner, fondatore e architetto principale del progetto LLVM e creatore del linguaggio di programmazione Swift. La sintassi di Mojo si basa sul linguaggio Python e il sistema di tipi è simile a C/C++. Il progetto si presenta come un linguaggio di programmazione generale che espande le capacità di Python con strumenti di programmazione di sistema, adatto a una vasta gamma di compiti e combinando la semplicità d'uso per progetti di ricerca e rapida prototipazione con l'idoneità per la creazione di prodotti finali ad alte prestazioni.
La semplicità è raggiunta grazie all'uso della sintassi familiare del linguaggio Python, mentre lo sviluppo di prodotti finali è facilitato dalla possibilità di compilazione in codice macchina, dai meccanismi di gestione sicura della memoria e dall'utilizzo di risorse per l'accelerazione hardware delle computazioni. Per garantire alte prestazioni, si supporta il parallelismo delle computazioni, sfruttando tutte le risorse hardware disponibili nei sistemi eterogenei, come le GPU, gli acceleratori specializzati per il machine learning e le istruzioni per processori vettoriali (SIMD). Nelle computazioni intensive, il parallelismo e l'uso di tutte le risorse computazionali consentono di raggiungere prestazioni superiori rispetto alle applicazioni in C/C++.
Il linguaggio supporta la tipizzazione statica e strumenti per una gestione sicura a basso livello della memoria, simili alle funzionalità del linguaggio Rust, come il tracciamento del ciclo di vita dei riferimenti e la verifica del prestito delle variabili (borrow checker). Inoltre, il linguaggio offre possibilità per operazioni a basso livello, come l'accesso diretto alla memoria in modalità unsafe con l'uso del tipo Pointer, l'invocazione di singole istruzioni SIMD o l'accesso a estensioni hardware come TensorCores e AMX.
Mojo può essere utilizzato sia in modalità interpretativa con JIT che per la compilazione in file eseguibili (AOT, ahead-of-time). Il compilatore include tecnologie moderne per l'ottimizzazione automatica, la cache e la compilazione distribuita. Il codice sorgente nel linguaggio Mojo viene convertito in un codice intermedio a basso livello MLIR (Multi-Level Intermediate Representation), sviluppato dal progetto LLVM. Il compilatore consente di utilizzare diversi backend che supportano MLIR per la generazione di codice macchina.
Tra le novità di Mojo 1.0.0b1:
- La parola chiave «fn» è stata dichiarata obsoleta; per dichiarare le funzioni si deve utilizzare la parola chiave «def» (le funzionalità di «fn» e «def» sono unite, e in «def» è implementata la semantica di «fn» senza generare eccezioni).
- È stata unificata l'implementazione delle closure. Le closure stateless ora vengono automaticamente convertite in funzioni di livello superiore e possono essere utilizzate come callback nelle FFI (Foreign Function Interface). È stato aggiunto il supporto per il riferimento per cattura. Nella dichiarazione delle funzioni è stata aggiunta l'indicazione «thin» per dichiarare un tipo semplice di puntatore a funzione senza catturare lo stato.
- I puntatori di tipo UnsafePointer ora non possono assumere un valore null di default, e per lavorare con puntatori null è necessario utilizzare «Optional[UnsafePointer[…]]», il che consente di eliminare i sovraccarichi quando si lavora con puntatori null e mantenere la possibilità di applicazione sicura nelle FFI.
- Di default, il codice per la CPU nelle collezioni include il controllo dei limiti validi (sulla GPU il controllo è disattivato per prestazioni, ma può essere abilitato durante la costruzione con «mojo build -D ASSERT=all»). È stato interrotto il supporto per l'indicazione di valori negativi negli indici (è vietato usare «x[-1]», ma può essere indicato «x[len(x)-1]»).
- Dal pacchetto standard è stato rimosso il tipo NDBuffer, al cui posto si deve utilizzare TileTensor.
- È stato ampliato il supporto per il lavoro con GPU attraverso l'API grafica Metal sui sistemi Apple (ad esempio, è stato aggiunto il supporto per print() e istruzioni matriciali M5). È stato introdotto il supporto per gli acceleratori AMD MI250X e NVIDIA B300.
- Gli identificatori dei primitivi GPU (indici di flusso e blocco) ora restituiscono il tipo Int anziché UInt.
- Il contesto CPU (‘DeviceContext(api=»cpu»)’) è diventato dipendente dal flusso (stream-ordered). Sono state aggiunte funzioni enqueue_cpu_function() e enqueue_cpu_range() per l'esecuzione ordinata delle attività.
- Nei tipi String e StringSlice è stato aggiunto il supporto per cluster di grapheme (Unicode UAX #29), che consente di calcolare correttamente la lunghezza e di tagliare le stringhe con emoji e simboli combinati. Sono stati aggiunti i metodi graphemes() e count_graphemes(), così come la sintassi per gli slice «[grapheme=…]».
- È stata implementata la raffinazione dei tipi (Type Refinement) in fase di compilazione per il restringimento automatico dei tipi all'interno di espressioni «where», «if» e «assert» (consente di evitare la specifica esplicita di trait_downcast).
- È stato proposto un API unificato per la riflessione, che include una nuova funzione reflect[T](), che restituisce Reflected[T] e sostituisce la famiglia di funzioni struct_field_* e i metodi obsoleti get_type_name().
Contemporaneamente, è stata rilasciata la versione 26.3 del motore MAX Framework, che offre una piattaforma per sviluppi nel campo del machine learning. MAX Framework integra gli strumenti di Mojo con risorse per sviluppare e debug applicazioni che utilizzano modelli di machine learning in vari formati (TensorFlow, PyTorch, ONNX, ecc.). Nella nuova versione di MAX Framework è stata aggiunta la possibilità di generare video, ampliato il supporto per l'uso di più GPU, e notevolmente migliorata la performance dell'interprete (alcune operazioni sono diventate fino a 10-20 volte più veloci).
Fonte: opennet.ru
