Racket (linguaggio di programmazione)
# Racket (linguaggio di programmazione)

Racket (precedentemente noto come PLT Scheme) è un linguaggio di programmazione general purpose multi-paradigma della famiglia Lisp-Scheme. Uno degli obiettivi dietro alla sua progettazione è quello di servire come piattaforma per la progettazione, creazione e implementazione di nuovi linguaggi. È usato in una varietà di contesti, come scripting, programmazione general purpose, didattica dell'informatica e ricerca.

La distribuzione fornisce un'implementazione del linguaggio (comprensiva di un sofisticato run-time system, diverse librerie e compilatore JIT) insieme con un ambiente di sviluppo integrato chiamato DrRacket (precedentemente noto come DrScheme) scritto esso stesso in Racket. Il linguaggio è noto per il suo versatile sistema di macro che consente di creare facilmente nuovi linguaggi e dialetti con diversi costrutti o una differente semantica.

La distribuzione è open source, coperta da licenza GNU Lesser General Public License (LGPL), ed estensioni e package realizzati dalla comunità sono disponibili attraverso un package manager centralizzato.

## Storia

### Sviluppo

Matthias Felleisen fondò PLT a metà degli anni 1990, dapprima come gruppo di ricerca, che poco dopo è divenuto un progetto orientato alla produzione di materiale didattico per programmatori. Nel gennaio 1995 il gruppo decise di creare un ambiente di programmazione didattico basato su Scheme. Matthew Flatt mise insieme MrEd, l'originale virtual machine, a partire da libscheme, wxWidgets e alcuni altri sistemi liberi. Negli anni successivi un team composto da Flatt, Robby Findler, Shriram Krishnamurthi, Cormac Flanagan e diversi altri realizzò DrScheme, un ambiente di sviluppo per novizi programmatori che costituiva anche un ambiente di ricerca per il soft typing. Il linguaggio principale supportato da DrScheme venne quindi chiamato PLT Scheme.

In parallelo, il team iniziò a tenere workshop per insegnanti delle scuole superiori, insegnando design e programmazione funzionale. Test sul campo condotti su questi insegnanti e i loro studenti furono importanti indizi per guidare lo sviluppo.

Negli anni seguenti il gruppo PLT ha aggiunto un tool noto come algebraic stepper, per la valutazione passo-passo delle espressioni, un interprete read-eval-print loop, un constructor-based printer, insieme a diversi altri strumenti. Nel 2001 i quattro sviluppatori principali del team (Felleisen, Findler, Flatt e Krishnamurthi) hanno pubblicato un libro che sintetizza la loro filosofia della didattica della programmazione, intitolato How to Design Programs.

### Versioni

La prima generazione di revisioni al linguaggio PLT Scheme ha introdotto costrutti per la programmazione su larga scala, con l'aggiunta di moduli e classi. La versione 42 ha introdotto le unità, un sistema di moduli first-class, complementari alle classi per lo sviluppo di programmi di grandi dimensioni. Il sistema di classi ha visto l'introduzione di interfacce in stile Java e l'eliminazione di alcune caratteristiche, come l'ereditarietà multipla. A partire dalla versione 53 il linguaggio ha acquisito una certa popolarità, e un rilascio principale è stato la versione 100, paragonabile alla versione 1.0 in un sistema di semantic versioning.

La successiva release principale è stata la 200, che ha introdotto un nuovo sistema di moduli predefinito, che si integra con il sistema di macro, garantendo la separazione tra valutazioni eseguite a run-time e a compile-time, permettendo quindi di creare una "torre di linguaggi". A differenza delle unità, questi moduli non sono oggetti di prima classe.

La versione 300 ha introdotto il supporto Unicode, FFI, e ritocchi al sistema di classi. Release successive nel ramo 300 hanno migliorato le prestazioni del runtime, con l'aggiunta di un compilatore JIT e un sistema predefinito per la generational garbage collection.

Con la nuova major release, il progetto è passato ad una numerazione delle versioni più convenzionale. La versione 4.0 ha introdotto la scorciatoia #lang per specificare il linguaggio nel quale un modulo è scritto, oltre a coppie e liste immutabili, supporto per il calcolo parallelo fine-grained, e un dialetto del linguaggio a tipizzazione statica.

### Ridenominazione

Il 7 giugno 2010, in concomitanza con la release 5.0, PLT Scheme è stato ribattezzato Racket. Nella versione 5.1 il backend dell'interfaccia grafica è stato riscritto da C++ a Racket stesso, usando un sistema di widget nativi su tutte le piattaforme. La versione 5.2 ha visto l'introduzione di un sistema di analisi statica del codice, una nuova libreria di plotting, una libreria di interfaccia database, e un nuovo REPL maggiormente esteso. La versione 5.3 ha introdotto, tra le varie novità, una funzionalità che permette il caricamento opzionale dei submodules, nuovi strumenti di ottimizzazione, una libreria JSON. Nella versione 5.3.1 sono state aggiunte alcune caratteristiche a DrRacket: il controllo sintattico è stato attivato come opzione predefinita, ed è stato aggiunto un sistema di anteprima della documentazione.

Nella versione 6.0 è stato introdotto un nuovo sistema di gestione dei pacchetti, con la riorganizzazione del repository e la suddivisione della distribuzione in un insieme di pacchetti più piccoli, permettendo un'installazione minimale di Racket con i pacchetti per le sole funzionalità desiderate.

## Caratteristiche

Il core di Racket comprende macro, moduli, chiusure lessicali, tail recursion, continuazione parziale, parametri, contratti, green threads e OS threads. Il linguaggio include anche alcune primitive, come eventspace e custodian, che controllano la gestione delle risorse e consentono di invocare e gestire programmi esterni. Il linguaggio è estensibile tramite il sistema di macro particolarmente versatile, che insieme al sistema di moduli e a parser personalizzati permette di controllare e modificare il linguaggio in tutti i suoi aspetti Molti costrutti dello stesso linguaggio Racket sono implementati come macro, tra i quali un sistema di classi mixin, e il meccanismo di pattern matching.

Racket è stato il primo linguaggio di programmazione di ordine superiore a introdurre un sistema di contratti. I contratti racket sono ispirati al design by Contract di Eiffel, che viene esteso per comprendere valori di ordine superiore, funzioni di prima classe, oggetti, reference e altre funzionalità. Ad esempio, un oggetto soggetto ad un contratto garantisce il controllo dei contratti quando i suoi metodi vengono invocati.

Il compilatore Racket traduce il sorgente in bytecode che viene eseguito dalla Racket virtual machine. Su sistemi x86 e PowerPC il bytecode viene compilato in codice nativo a runtime da un compilatore JIT.

Nel 2004 è stato introdotto PLaneT, un package manager integrato nel sistema di moduli che consente di importare e usare librerie di terze parti in maniera trasparente. PLaneT include anche un proprio sistema di versioning per evitare situazioni di dependency hell. Nel 2014 buona parte del codice Racket è stato spostato in un nuovo sistema di pacchetti separato dalla codebase principale, gestito da un client chiamato raco. Il nuovo sistema di pacchetti fornisce meno funzionalità rispetto a PLaneT.

### Sistema di macro

Una tra le principali caratteristiche che distingue Racket dagli altri linguaggi della famiglia Lisp è la sua estensibilità intrinseca. Le funzionalità di estensibilità di Racket sono integrate nel sistema di moduli, consentendo un controllo sulla sintassi a livello dei moduli stessi. Ad esempio, la forma sintattica #%app può essere riscritta per modificare la semantica della chiamata di funzione. Analogamente, la forma sintattica #%module-begin permette di eseguire un'analisi statica arbitraria dell'intero modulo. Ogni modulo può essere usato come un linguaggio, grazie alla notazione #lang, e il programmatore può controllare virtualmente ogni aspetto del linguaggio stesso.

L'estensibilità fornita dai moduli viene combinata con il sistema di macro igieniche analogo a Scheme, che fornisce funzionalità aggiuntive rispetto al sistema per la manipolazione delle S-expression del Lisp, al sistema di macro di Scheme 84 o alle regole sintattiche di R5RS. Con queste funzionalità i programmatori possono aggiungere funzionalità e creare linguaggi specifici in maniera totalmente indistinguibile dalle funzionalità built-in del linguaggio.

Il sistema di macro di Racket è stato usato per l'implementazione di dialetti, tra i quali Typed Racket, una versione del linguaggio che fornisce un sistema di tipi, e Lazy Racket, un dialetto che usa un sistema di valutazione lazy. Altri dialetti sono FrTime (programmazione reattiva funzionale), Scribble (un linguaggio per la produzione di documentazione), Slideshow (un linguaggio per la realizzazione di slide), e diversi altri. Racket fornisce alcune librerie che facilitano l'implementazione di nuovi linguaggi.

I nuovi linguaggi non sono ristretti alla sintassi basata su S-expression, permettendo la definizione di parser arbitrari, ad esempio usando la libreria di strumenti di parsing fornita da Racket stesso.

## Ambiente di sviluppo

La distribuzione Racket fornisce un IDE chiamato DrRacket, un web server basato su continuazione, una graphical user interface, e diversi altri strumenti. Racket è anche utilizzabile come strumento di scripting, ad esempio negli script per shell Unix. Può eseguire il parsing di parametri a riga di comando, eseguire tool esterni e includere librerie.

### DrRacket

DrRacket (precedentemente noto come DrScheme) è un ambiente di sviluppo disponibile per Microsoft Windows, macOS, Unix e Linux, spesso usato come strumento didattico nei corsi introduttivi alla programmazione, inizialmente sviluppato come strumento per il progetto TeachScheme! (divenuto poi ProgramByDesign), avviato dalla Northeastern University in collaborazione con alcune altre università per l'insegnamento della programmazione nelle scuole superiori.

L'editor fornisce syntax highlighting, matching delle parentesi, debugger e algebraic stepper. Permette di scegliere diversi "livelli" (principiante, intermedio, etc.) per semplificare l'ambiente agli studenti. Ha un supporto integrato per le librerie e un sistema di analisi statica utile per i programmatori esperti. Fornisce un browser per i moduli, un sistema di testing e fault coverage integrati, supporto per il refactoring, e un sistema di accesso alla documentazione.

## Esempi

Un esempio di hello world in Racket è il seguente:

che quando eseguito visualizza la scritta "Hello, World!".

Il seguente è un esempio di definizione di una funzione ricorsiva per il calcolo del fattoriale:

## Applicazioni ed utilizzi

Oltre all'uso come strumento didattico e nella ricerca, Racket è stato pensato come linguaggio general purpose per l'uso su sistemi di produzione. Per tale motivo, la distribuzione fornisce estese librerie che supportano programmazione di sistema e di rete, sviluppo web, un'interfaccia per accedere alle chiamate del sistema operativo, FFI, varie implementazioni di regex, generatori di lexer e parser, programmazione logica, ed un widget toolkit.

Tra le funzionalità di Racket utili per lo sviluppo di applicazioni commerciali vi sono la possibilità di generare eseguibili nativi in ambiente Windows, macOS e Unix/Linux, profiler e debugger inclusi nell'ambiente di sviluppo integrato e un framework di unit test.

Racket è usato in progetti commerciali e applicazioni web. Tra gli esempi, il sito web Hacker News impiega Arc, che è sviluppato in Racket. Naughty Dog ha usato Racket come linguaggio di scripting per diversi videogame.

Racket è usato per l'insegnamento dell'algebra tramite game design nel programma bootstrap curriculum.

