Hack: un nou limbaj de programare pentru HHVM – Facebook Engineering

Te grăbești? Încercați Hack acum: http://hacklang.org/

Astăzi lansăm Hack, un limbaj de programare pe care l-am dezvoltat pentru HHVM și care interacționează perfect cu PHP. Hack reconciliază ciclul rapid de dezvoltare al PHP cu disciplina oferită de tastarea statică, adăugând în același timp multe caracteristici întâlnite în mod obișnuit în alte limbaje de programare moderne.

Am implementat Hack la Facebook și a fost un mare succes. Pe parcursul ultimului an, am migrat aproape întreaga noastră bază de cod PHP la Hack, datorită atât adoptării organice, cât și a unui număr de instrumente de refactorizare de producție proprie.

Suntem, de asemenea, mândri să lansăm o versiune open source de Hack pentru public la http://hacklang.org/ ca parte a platformei noastre de execuție HHVM, care va suporta acum atât Hack cât și PHP.

Motivație

Care programator PHP este familiarizat cu sarcini zilnice care pot fi dificile sau greoaie. Codul de mai sus este un exemplu excelent de greșeală frecventă în care o metodă ar putea fi apelată în mod neașteptat pe un obiect nul, provocând o eroare care nu ar fi detectată până în timpul execuției. Un alt exemplu este un API complex, unde dezvoltatorii pot avea o înțelegere solidă a semanticii sale, dar totuși petrec timp căutând nume de metode banale în documentație.

La scara Facebook – cu mii de ingineri care expediază cod nou de două ori pe zi – încetiniri ca acestea sunt și mai problematice. Înainte de Hack, aveam un limbaj simplu cu o buclă de feedback rapidă – dar cum am putea atenua tipurile de probleme descrise mai sus? Ar putea coexista detectarea timpurie a erorilor cu iterația rapidă, totul păstrând în același timp investiția noastră în PHP? Ar putea o analiză și o introspecție îmbunătățită a codului să contribuie la creșterea productivității dezvoltatorilor cu instrumente precum autocompletarea?

În mod tradițional, limbajele tipizate dinamic permit o dezvoltare rapidă, dar sacrifică capacitatea de a detecta erorile din timp și de a introspecta rapid codul, în special în cazul bazelor de cod mai mari. Dimpotrivă, limbajele tipizate static oferă o plasă de siguranță mai mare, dar adesea cu prețul iterației rapide. Am crezut că trebuie să existe un punct dulce.

Așa s-a născut Hack. Credem că oferă ce este mai bun atât din limbajele tipizate dinamic, cât și din cele tipizate static, și că va fi valoros pentru proiecte de toate dimensiunile.

Limbajul Hack

Hack are rădăcini adânci în PHP. De fapt, majoritatea fișierelor PHP sunt deja fișiere Hack valide. Am făcut o alegere conștientă de a nu susține o mână de funcții și caracteristici depreciate care erau incompatibile cu tipizarea statică (de exemplu, „variabilele variabile” și funcția extract()). Am adăugat, de asemenea, multe funcții noi care credem că vor ajuta dezvoltatorii să fie mai productivi.

Principalul nostru adaos este tastarea statică. Am dezvoltat un sistem de adnotare a semnăturilor funcțiilor și a membrilor clasei cu informații despre tip; algoritmul nostru de verificare a tipului („type checker”) deduce restul. Verificarea tipurilor este incrementală, astfel încât, chiar și în cadrul unui singur fișier, o parte din cod poate fi transformat în Hack, în timp ce restul rămâne tipizat dinamic. Din punct de vedere tehnic, Hack este un limbaj „tipizat treptat*”*: codul tipizat dinamic interacționează fără probleme cu codul tipizat static.

În cadrul sistemului de tipuri Hack, am introdus mai multe caracteristici, cum ar fi genericele, tipurile care se pot anula, aliasing-ul de tip și constrângerile asupra parametrilor de tip. Aceste noi caracteristici ale limbajului sunt discrete, astfel încât codul pe care îl scrieți cu Hack va arăta și se va simți în continuare ca limbajul dinamic cu care programatorii PHP sunt obișnuiți.

Cu toate acestea, Hack adaugă caracteristici suplimentare dincolo de verificarea statică a tipurilor, inclusiv Colecții, expresii lambda și impunerea în timp de execuție a tipurilor de retur și a tipurilor de parametru.

Colecțiile oferă o alternativă curată și sigură din punct de vedere al tipurilor la matricele PHP. Le-am proiectat în mod special pentru a funcționa bine cu tipărirea statică și genericele. API-ul Collections oferă multe funcții clasice de ordin superior, cum ar fi map() și filter(), pentru a facilita stilurile de programare funcțională.

Expresiile Lambda oferă o sintaxă concisă pentru crearea de închideri. Deși PHP are închideri, acesta cere programatorului să numească în mod explicit variabilele pe care trebuie să le folosească din sferele de cuprindere închise. Cu expresiile lambda de la Hack, deducem automat aceste utilizări, economisind munca inutilă. Expresiile lambda fac mai convenabil să profitați pe deplin de API-ul Collections.

Aplicarea în timp de execuție a tipurilor de returnare și a tipurilor de parametri (inclusiv a tipurilor scalare precum int și string) oferă siguranță dincolo de ceea ce poate fi verificat static în timp ce adnotările de tip sunt adăugate treptat la o bază de cod. Punerea în aplicare în timp de execuție îi ajută pe programatori să detecteze și să diagnosticheze mai ușor anumite tipuri de probleme și ajută JIT-ul HHVM să producă un cod mai eficient, făcând sigură încrederea în adnotările de tip în scopuri de optimizare.

Controlul instantaneu al tipurilor

În timpul dezvoltării, un programator PHP merge, de obicei, înainte și înapoi rapid între codul sursă și browser. Inginerii pot itera cât de repede au nevoie, testând și ajustând o experiență până când aceasta este perfectă.

În mod tradițional, un verificator de tip ar întrerupe această buclă de feedback, deoarece este nevoie de timp pentru a analiza codul sursă. Nu am vrut să încetinim fluxul de lucru PHP, așa că am venit cu o nouă abordare pentru a reconcilia feedback-ul instantaneu cu siguranța tipurilor.

Soluția noastră a fost de a arhitectura verificatorul de tip ca un server local care urmărește sistemul de fișiere. Serverul păstrează toate informațiile despre codul sursă în memorie și se actualizează automat atunci când un fișier se modifică pe disc. Această abordare a dat roade: verificatorul de tipuri rulează de obicei în mai puțin de 200 de milisecunde și rareori durează mai mult de o secundă, ceea ce îl face ușor de integrat în fluxul de lucru al dezvoltării fără a introduce o întârziere notabilă.

Migrarea codului

Beneficiile de siguranță a tipurilor și de refactorizare ale lui Hack cresc cu cât este mai mult utilizat în cadrul unei baze de cod. Înțelegând că ar fi dificil ca unele coduri să fie complet trecute imediat la Hack, a fost important pentru noi ca Hack să fie dezvoltat astfel încât să poată coexista direct cu alte fișiere PHP pe măsură ce este introdus treptat.

Restul procesului de conversie, cum ar fi adăugarea de adnotări de tip și utilizarea noilor caracteristici ale limbajului, se poate face după cum este adecvat pentru baza de cod. De exemplu, o adnotare de tip poate fi adăugată pentru o funcție, dar omisă pentru o altă funcție, chiar și în același fișier. Dacă un parametru de funcție sau un membru de clasă nu are o adnotare de tip explicită, verificatorul de tip consideră că tipul său este dinamic și nu verifică tipul acelei valori.

În cadrul Facebook, am constatat că inginerii noștri au apreciat Hack suficient de mult încât au început să convertească în mod voluntar majoritatea codului propriu. Cu milioane de linii de cod în arborele nostru, am dorit, de asemenea, o anumită formă de automatizare, așa că am construit și folosim o serie de instrumente de modificare a codului pentru a asista procesul (pe care le lansăm ca parte a Hack).

Nu vă faceți griji, PHP-ul dumneavoastră este în siguranță!

HHVM este încă un timp de execuție PHP și intenționăm să-l păstrăm așa. De fapt, lucrăm din greu pentru a ajunge la paritate cu PHP-5. Una dintre prioritățile de top ale HHVM este să ruleze codul sursă PHP-5 nemodificat, atât pentru comunitate, cât și pentru că ne bazăm pe bibliotecile PHP de la terți la nivel intern.

HHVM este acum un timp de execuție care suportă *atât PHP cât și Hack, astfel încât puteți începe să profitați de noile caracteristici ale lui Hack în mod incremental.

Distracție plăcută cu Hack!

Suntem încântați să deschidem atât Hack cât și instrumentele pe care le puteți folosi pentru a vă converti automat baza de cod. Acesta este doar primul pas și suntem dedicați să continuăm să evoluăm acest software pentru a face dezvoltarea și mai ușoară atât pentru inginerii noștri, cât și pentru comunitatea mai largă. Valoarea lui Hack nu este *nu* limitată la proiectele mari: cu informații despre tipuri, mesaje de eroare bune și feedback rapid, bazele de cod de dimensiuni mici pot beneficia și ele de avantajele lui Hack.

Luna viitoare, vom prezenta limbajul și la Ziua Dezvoltatorilor Hack din campusul Facebook din Menlo Park și sperăm să vă vedem acolo în persoană sau online.

Ne-ar plăcea să primim feedback-ul dumneavoastră cu privire la munca noastră de până acum și vă invităm pe toți să participați la comunitatea HHVM și Hack.

Recunoștințe

Există multe persoane care au contribuit la dezvoltarea Hack.

Echipa de bază Hack este formată din Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar și Joshua Van Dyke Watzman.

Mulțumim în mod special celor care au adoptat timpuriu comunitatea noastră pentru că au oferit feedback valoros pentru a face limbajul mai bun: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier și Alexander Mols.

Hack este scris în principal în OCaml. Am dori să mulțumim echipei Gallium (INRIA) pentru dezvoltarea limbajului OCaml și echipei Ocsigen (CNRS – Universitatea Paris Diderot – INRIA) pentru dezvoltarea părții js_of_ocaml din Ocsigen.

Și, bineînțeles, mulțumim tuturor celor care au contribuit la transformarea lui Hack în limbajul care este astăzi. Lista este prea exhaustivă pentru o postare pe blog, dar știți cine sunteți.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.