# Rust (linguaggio di programmazione)

Rust è un linguaggio di programmazione compilato, multi-paradigma, ad uso generale, sviluppato da Mozilla Research, in collaborazione con la comunità open-source. Si pone l'obiettivo di essere un linguaggio efficiente, sicuro, e idoneo a sviluppare software di sistema concorrente. È progettato per permettere i paradigmi di programmazione imperativo, procedurale, funzionale, e orientata agli oggetti.
Il linguaggio è emerso da un progetto personale di un dipendente di Mozilla, Graydon Hoare. Il sostegno al progetto da parte di Mozilla è cominciato nel 2009 ed è stato annunciato nel 2010. Lo stesso anno è iniziata la riscrittura in Rust del compilatore stesso, inizialmente scritto in OCaml. Questo compilatore, noto come rustc, è riuscito a compilare sé stesso nel 2011. Come back end usa il framework open source LLVM.
La prima versione del compilatore di Rust è stata pubblicata nel gennaio del 2012. La prima versione stabile, la 1.0, è uscita il 15 maggio 2015.
Sebbene lo sviluppo sia sostenuto da Mozilla, si tratta di un progetto aperto alla comunità open-source, che contribuisce attivamente. La progettazione del linguaggio è stata raffinata dall'esperienza di utilizzo nello sviluppo del motore di browser Web Servo e del compilatore rustc.
In un sondaggio effettuato nel 2016 tra gli iscritti di Stack Overflow, Rust si è classificato al primo posto come "linguaggio di programmazione più amato" (Most Loved Programming Language). Questa posizione è stata confermata anche nei sondaggi del 2017, del 2018, del 2019, del 2020, del 2021 e del 2022.
Si ritiene che il linguaggio prenda il nome dal nome inglese delle ruggini, specie di funghi che attaccano le foglie delle piante.

## Progettazione

L'obiettivo di Rust è di essere un buon linguaggio per creare sistemi complessi altamente sicuri, anche nel caso siano multi threaded. Ciò ha condotto a un insieme di caratteristiche che enfatizzano le prestazioni, il controllo dell'allocazione di memoria, la sicurezza e la concorrenza.
Riguardo alle prestazioni, ogni tipico programma scritto in Rust ha una maggiore sicurezza sulla scrittura in memoria rispetto al C++ cercando di mantenere la stessa velocità di quest'ultimo per la maggior parte delle applicazioni. I tempi di compilazione sono però più lunghi.
Riguardo all'allocazione di memoria, ogni tipo usa un numero di bit definito dal linguaggio e ha un allineamento definibile dal programmatore, inoltre non viene usata la garbage collection, consentendo una deallocazione deterministica della memoria.
Riguardo alla sicurezza, il linguaggio vieta costrutti dal comportamento indefinito, come la lettura di variabili non ancora scritte, l'accesso oltre i limiti di array, la dereferenziazione di puntatori nulli o non validi, l'uso di iteratori invalidati.
Nonostante l'assenza di garbage collection, la memoria allocata dinamicamente viene deallocata automaticamente grazie al fatto che il compilatore inserisce le opportune istruzioni quando le variabili escono dal proprio ambito di visibilità. I memory leak sono considerati sicuri, ma si possono verificare solo in particolari situazioni: ad esempio chiamando apposite funzioni di libreria (Box::leak, std::mem::forget, ...) o creando cicli di puntatori reference counted (Rc, Arc).
Riguardo alla sicurezza della concorrenza, il linguaggio impedisce operazioni concorrenti dall'esito indefinito, come l'accesso simultaneo in scrittura alla stessa variabile.
La sintassi di Rust somiglia a quella del linguaggio C per l'uso delle graffe per racchiudere strutture o blocchi di istruzioni, per gli operatori aritmetici e logici, e per le parole chiave di controllo del flusso if, else, for, while, break, continue, e return. I tipi primitivi di Rust sono analoghi ai tipi del C, anche se con nomi quasi tutti diversi. Tuttavia la semantica di Rust è parecchio diversa da quelle di C e C++.
Il sistema dei tipi supporta un costrutto detto trait, ispirato dal linguaggio Haskell, che consente l'ereditarietà multipla di interfacce, ma non l'ereditarietà di implementazione. Questa ereditarietà può essere sia statica, analoga ai trait dei template del C++, sia dinamica, analoga alle funzioni virtuali del C++.
Rust è dotato di inferenza di tipo, cioè ogni volta che si dichiara una variabile locale, è facoltativo dichiararne il tipo. Quest'ultimo viene desunto dall'espressione di inizializzazione o dalle successive istruzioni di assegnamento a tale variabile.
Non è obbligatorio inizializzare le variabili. Tuttavia viene generato errore di compilazione se una variabile viene usata prima di ricevere un valore, o se le vengono assegnati valori di tipi diversi.
Le classi (chiamate struct) e le funzioni possono essere parametrizzate da tipi in modo analogo ai template del C++. Tuttavia questi tipi parametrici devono essere vincolati a dei trait per poterne usare i metodi o gli operatori.
Rust si differenzia da molti altri linguaggi object-oriented per le seguenti scelte progettuali:
* si usano i concetti di "proprietà" (in inglese ownership) degli oggetti, e di "prestito" (in inglese borrowing) degli oggetti per decidere quali istruzioni possono leggere un oggetto e quali lo possono scrivere;
* si consente, e talvolta si richiede, che il programmatore specifichi un "tempo di vita" (in inglese lifetime) associato a oggetti gestiti tramite puntatori, per decidere quando tali oggetti devono essere distrutti;
* non si usa il concetto di eccezione;
* non si usa l'ereditarietà di implementazione, cioè ogni classe può ereditare solo da interfacce, non da altre classi;
* le classi non sono oggetti, ovvero non esistono metaclassi;
* le classi non hanno eredità implicita da una interfaccia comune;
* non si usa l'overload delle funzioni, cioè nello stesso ambito le funzioni devono avere nomi diversi;
* non si usa né la riflessione né la valutazione di espressioni in fase di esecuzione (eval).

## Storia

Lo stile del sistema ad oggetti è cambiato considerevolmente tra le versioni 0.2, 0.3 e 0.4 di Rust. La version 0.2 ha introdotto le classi. La versione 0.3 ha aggiunto alcune funzionalità tra cui i distruttori e il polimorfismo tramite l'uso delle interfacce. In Rust 0.4, i trait sono stati aggiunti come mezzo per fornire l'ereditarietà, le interfacce sono state unificate nei trait e quindi rimosse come funzionalità distinta. Anche le classi sono state rimosse, sostituite da una combinazione di strutture e di implementazioni.
A partire dalla versione 0.9 e fino alla versione 0.11, Rust aveva due tipi di puntatori, ~ e @, il che semplificava il modello di memoria interno. Il primo di quei tipi di puntatori è stato sostituito dalla funzione di libreria Box e il secondo, che usava la garbage collection, è stato eliminato.
Dato che il motivo principale per cui nessuno adottava Rust era il fatto che il linguaggio ad ogni cambio di versione diventava incompatibile con la versione precedente, all'uscita della 1.0, la prima versione stabile, è stato promesso che le successive versioni 1.x sarebbero state compatibili con essa.
L'8 febbraio 2021 lo sviluppo del linguaggio passa ufficialmente sotto il controllo della Rust Foundation, organizzazione non-profit indipendente, finanziata da Mozilla, Microsoft, Google, AWS e Huawei.

## Utilizzo

Le caratteristiche di sicurezza, concorrenza e le elevate prestazioni di Rust hanno attirato l'interesse di molte realtà differenti, portando il linguaggio ad essere usato in diversi ambiti.
Di seguito alcuni esempi:
* Sviluppo web: scrittura di codice WebAssembly; sviluppo di applicazioni web con il framework Rocket.
* Applicazioni server: Dropbox ha usato Rust per implementare un proprio back-end, separandosi dai servizi Amazon; Cloudflare ha usato Rust per implementare un interprete TCP/IP ad alte prestazioni.
* Sviluppo di videogiochi: scrittura di motori grafici, come ad esempio Bevy; lo studio di Ready at Dawn usa Rust come linguaggio principale per lo sviluppo di nuovi giochi.
* Sistemi operativi: implementazione di nuovi driver all'interno del kernel Linux; sviluppo di Redox, un SO Unix-like scritto interamente in Rust; Google Fuchsia contiene parti scritte in Rust e supporta il linguaggio per la scrittura di applicazioni native.
* Sviluppo embedded: scrittura e compilazione del codice in formato binario per core ARM Cortex-M ed altri target, sprovvisti del supporto di un sistema operativo.

## Esempi

Hello world:
Tre versioni della funzione fattoriale, rispettivamente usando gli stili ricorsivo, iterativo, e funzionale:
Una semplice dimostrazione delle potenzialità di concorrenza di Rust:
Ecco una dimostrazione degli smart pointer univoci forniti da Rust, insieme alle union taggate e ai metodi: