Hack: un nuovo linguaggio di programmazione per HHVM – Facebook Engineering

Ha fretta? Prova Hack ora: http://hacklang.org/

Oggi rilasciamo Hack, un linguaggio di programmazione che abbiamo sviluppato per HHVM e che interagisce perfettamente con PHP. Hack concilia il veloce ciclo di sviluppo di PHP con la disciplina fornita dalla tipizzazione statica, aggiungendo molte caratteristiche che si trovano comunemente in altri linguaggi di programmazione moderni.

Abbiamo distribuito Hack a Facebook ed è stato un grande successo. Nel corso dell’ultimo anno, abbiamo migrato quasi tutto il nostro codice PHP ad Hack, grazie sia all’adozione organica che ad una serie di strumenti di refactoring fatti in casa.

Siamo anche orgogliosi di rilasciare una versione open source di Hack al pubblico a http://hacklang.org/come parte della nostra piattaforma runtime HHVM, che ora supporterà sia Hack che PHP.

Motivazione

Ogni programmatore PHP ha familiarità con compiti quotidiani che possono essere difficili o ingombranti. Il codice qui sopra è un ottimo esempio di un errore comune in cui un metodo potrebbe essere chiamato inaspettatamente su un oggetto nullo, causando un errore che non verrebbe catturato fino al runtime. Un altro esempio è un’API complessa, dove gli sviluppatori possono avere una solida comprensione della sua semantica, ma passano comunque del tempo a cercare nomi di metodi banali nella documentazione.

Alla scala di Facebook – con migliaia di ingegneri che spediscono nuovo codice due volte al giorno – rallentamenti come questi sono ancora più problematici. Prima di Hack, avevamo un linguaggio semplice con un ciclo di feedback veloce – ma come potevamo mitigare il tipo di problemi descritti sopra? Il rilevamento precoce degli errori poteva coesistere con una rapida iterazione, il tutto preservando il nostro investimento in PHP? Una migliore analisi del codice e l’introspezione potrebbero aiutare a rendere gli sviluppatori più produttivi con strumenti come il completamento automatico?

Tradizionalmente, i linguaggi tipizzati dinamicamente permettono uno sviluppo rapido, ma sacrificano la capacità di individuare precocemente gli errori e l’introspezione del codice rapidamente, in particolare su codebase più grandi. Al contrario, i linguaggi tipizzati staticamente forniscono più di una rete di sicurezza, ma spesso al costo di una rapida iterazione. Abbiamo creduto che ci dovesse essere un punto dolce.

Così è nato Hack. Crediamo che offra il meglio di entrambi i linguaggi tipizzati dinamicamente e staticamente, e che sarà prezioso per progetti di tutte le dimensioni.

Il linguaggio Hack

Hack ha profonde radici in PHP. Infatti, la maggior parte dei file PHP sono già file Hack validi. Abbiamo fatto una scelta consapevole di non supportare una manciata di funzioni deprecate e caratteristiche che erano incompatibili con la tipizzazione statica (ad esempio le “variabili variabili” e la funzione extract()). Abbiamo anche aggiunto molte nuove caratteristiche che crediamo possano aiutare a rendere gli sviluppatori più produttivi.

La nostra principale aggiunta è la tipizzazione statica. Abbiamo sviluppato un sistema per annotare le firme delle funzioni e i membri delle classi con informazioni sul tipo; il nostro algoritmo di controllo del tipo (il “type checker”) infonde il resto. Il controllo dei tipi è incrementale, così che anche all’interno di un singolo file un po’ di codice può essere convertito in Hack mentre il resto rimane tipizzato dinamicamente. Tecnicamente parlando, Hack è un linguaggio “gradualmente tipizzato*”*: il codice dinamicamente tipizzato interagisce senza problemi con il codice staticamente tipizzato.

All’interno del sistema dei tipi di Hack, abbiamo introdotto diverse caratteristiche come i generici, i tipi nullable, l’aliasing dei tipi e i vincoli sui parametri dei tipi. Queste nuove caratteristiche del linguaggio sono discrete, quindi il codice che scriverete con Hack avrà ancora l’aspetto e la sensazione del linguaggio dinamico a cui i programmatori PHP sono abituati.

Tuttavia, Hack aggiunge ulteriori caratteristiche oltre al controllo statico dei tipi, incluse le collezioni, le espressioni lambda e l’applicazione run-time dei tipi di ritorno e dei tipi di parametro.

Le collezioni forniscono un’alternativa pulita e sicura agli array di PHP. Le abbiamo progettate specificamente per lavorare bene con la tipizzazione statica e i generici. L’API Collections offre molte funzioni classiche di ordine superiore come map() e filter() per facilitare gli stili di programmazione funzionale.

Le espressioni Lambda danno una sintassi concisa per creare chiusure. Anche se PHP ha delle chiusure, richiede al programmatore di nominare esplicitamente le variabili che hanno bisogno di usare dagli scopes che le racchiudono. Con le espressioni lambda di Hack, deduciamo automaticamente questi usi, risparmiandovi del lavoro inutile. Le espressioni lambda rendono più conveniente trarre pieno vantaggio dalle API Collections.

L’applicazione run-time dei tipi di ritorno e dei tipi di parametro (inclusi i tipi scalari come int e string) fornisce sicurezza al di là di ciò che può essere controllato staticamente mentre le annotazioni di tipo vengono gradualmente aggiunte al codice. L’applicazione run-time aiuta i programmatori a rilevare e diagnosticare più facilmente certi tipi di problemi, e aiuta il JIT di HHVM a produrre codice più efficiente rendendo sicura la fiducia nelle annotazioni di tipo per scopi di ottimizzazione.

Controllo istantaneo dei tipi

Durante lo sviluppo, un programmatore PHP tipicamente va avanti e indietro rapidamente tra il codice sorgente e il browser. Gli ingegneri possono iterare tanto velocemente quanto hanno bisogno, testando e mettendo a punto un’esperienza finché non è perfetta.

Tradizionalmente, un type checker interromperebbe questo ciclo di feedback poiché richiede tempo per analizzare il codice sorgente. Non volevamo rallentare il flusso di lavoro di PHP, quindi abbiamo ideato un nuovo approccio per conciliare il feedback istantaneo con la sicurezza dei tipi.

La nostra soluzione è stata quella di architettare il type checker come un server locale che guarda il filesystem. Il server mantiene tutte le informazioni sul codice sorgente in memoria e si aggiorna automaticamente quando un file cambia sul disco. Questo approccio ha dato i suoi frutti: il type checker tipicamente viene eseguito in meno di 200 millisecondi e raramente impiega più di un secondo, rendendolo facile da integrare nel flusso di lavoro dello sviluppo senza introdurre un notevole ritardo.

Migrazione del codice

La sicurezza dei tipi e i benefici di refactoring di Hack crescono più viene usato all’interno di una base di codice. Comprendendo che sarebbe stato difficile per alcuni codici passare completamente ad Hack immediatamente, era importante per noi che Hack fosse sviluppato in modo tale da poter coesistere direttamente con altri file PHP mentre veniva introdotto in modo incrementale.

Il resto del processo di conversione, come l’aggiunta di annotazioni di tipo e l’uso di nuove caratteristiche del linguaggio, può essere fatto come appropriato per la codebase. Per esempio, un’annotazione di tipo può essere aggiunta per una funzione ma lasciata fuori da un’altra funzione, anche nello stesso file. Se un parametro di funzione o un membro di classe non ha un’annotazione di tipo esplicita, il type checker considera il suo tipo come dinamico, e non controlla il tipo di quel valore.

In Facebook, abbiamo scoperto che i nostri ingegneri hanno apprezzato Hack abbastanza da iniziare a convertire la maggior parte del loro codice volontariamente. Con milioni di linee di codice nel nostro albero, volevamo anche una qualche forma di automazione, così abbiamo costruito e usiamo una serie di strumenti di modifica del codice per assistere il processo (che stiamo rilasciando come parte di Hack).

Non preoccupatevi, il vostro PHP è sicuro!

HHVM è ancora un runtime PHP, e abbiamo intenzione di mantenerlo tale. Infatti, stiamo lavorando duramente per raggiungere la parità con PHP-5. Una delle massime priorità di HHVM è quella di eseguire codice sorgente PHP-5 non modificato, sia per la comunità sia perché internamente ci affidiamo a librerie PHP di terze parti.

HHVM è ora un runtime che supporta *entrambi* PHP e Hack, così potete iniziare a sfruttare le nuove caratteristiche di Hack in modo incrementale.

Divertitevi con Hack!

Siamo felici di rendere open-source sia Hack che gli strumenti che potete usare per convertire automaticamente la vostra codebase. Questo è solo il primo passo, e siamo impegnati a continuare ad evolvere questo software per rendere lo sviluppo ancora più facile sia per i nostri ingegneri che per la comunità più ampia. Il valore di Hack non è *non* limitato ai grandi progetti: con informazioni sui tipi, buoni messaggi di errore e feedback veloce, anche le piccole codebase possono raccogliere i benefici di Hack.

Il mese prossimo, presenteremo il linguaggio all’Hack Developer Day nel campus di Facebook a Menlo Park, e speriamo di vedervi lì di persona o online.

Ci piacerebbe avere il vostro feedback sul nostro lavoro finora, e vi invitiamo a partecipare alla comunità HHVM e Hack.

Riconoscimenti

Ci sono molte persone che hanno contribuito allo sviluppo di Hack.

Il team di Hack è composto da Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar e Joshua Van Dyke Watzman.

Un ringraziamento speciale va ai primi adottanti della nostra comunità per aver fornito un prezioso feedback per migliorare il linguaggio: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier e Alexander Mols.

Hack è scritto principalmente in OCaml. Vorremmo ringraziare il team Gallium (INRIA) per lo sviluppo del linguaggio OCaml, e il team Ocsigen (CNRS – Università di Parigi Diderot – INRIA) per lo sviluppo della parte js_of_ocaml di Ocsigen.

E, naturalmente, grazie a tutti coloro che hanno contribuito a rendere Hack il linguaggio che è oggi. La lista è troppo esaustiva per un post sul blog, ma voi sapete chi siete.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.