Hack: et nyt programmeringssprog til HHVM – Facebook Engineering

Har du travlt? Prøv Hack nu: http://hacklang.org/

I dag udgiver vi Hack, et programmeringssprog, som vi har udviklet til HHVM, og som fungerer problemfrit sammen med PHP. Hack forener den hurtige udviklingscyklus i PHP med den disciplin, som statisk typning giver, samtidig med at der tilføjes mange funktioner, der almindeligvis findes i andre moderne programmeringssprog.

Vi har implementeret Hack hos Facebook, og det har været en stor succes. I løbet af det sidste år har vi migreret næsten hele vores PHP-kodebase til Hack, takket være både organisk adoption og en række hjemmebyggede refaktoriseringsværktøjer.

Vi er også stolte af at frigive en open source-version af Hack til offentligheden på http://hacklang.org/ som en del af vores HHVM runtime-platform, som nu vil understøtte både Hack og PHP.

Motivation

Alle PHP-programmører er bekendt med daglige opgaver, der kan være vanskelige eller besværlige. Koden ovenfor er et godt eksempel på en almindelig fejl, hvor en metode uventet kunne blive kaldt på et null-objekt, hvilket forårsager en fejl, som ikke ville blive opdaget før køretid. Et andet eksempel er et komplekst API, hvor udviklerne måske har en solid forståelse af dets semantik, men stadig bruger tid på at slå banale metodebetegnelser op i dokumentationen.

På Facebooks skala – med tusindvis af ingeniører, der sender ny kode to gange om dagen – er langsommere opbremsninger som disse endnu mere problematiske. Før Hack havde vi et simpelt sprog med et hurtigt feedback loop – men hvordan kunne vi afhjælpe den slags problemer, der er beskrevet ovenfor? Kunne tidlig fejlfinding eksistere side om side med hurtig iteration, samtidig med at vi bevarede vores investering i PHP? Kunne forbedret kodeanalyse og introspektion hjælpe med at gøre udviklerne mere produktive med værktøjer som auto-complete?

Traditionelt giver dynamisk typede sprog mulighed for hurtig udvikling, men de ofrer evnen til at opdage fejl tidligt og introspicere kode hurtigt, især på større kodebaser. Omvendt giver statisk typede sprog mere af et sikkerhedsnet, men ofte på bekostning af hurtig iteration. Vi mente, at der måtte være et sweet spot.

Dermed blev Hack født. Vi mener, at det tilbyder det bedste fra både dynamisk typede og statisk typede sprog, og at det vil være værdifuldt for projekter af alle størrelser.

Sproget Hack

Hack har dybe rødder i PHP. Faktisk er de fleste PHP-filer allerede gyldige Hack-filer. Vi har truffet et bevidst valg om ikke at understøtte en håndfuld forældede funktioner og funktioner, der var uforenelige med statisk typning (f.eks. “variable variabler” og funktionen extract()). Vi har også tilføjet mange nye funktioner, som vi mener vil hjælpe med at gøre udviklere mere produktive.

Vores vigtigste tilføjelse er statisk typning. Vi har udviklet et system til at annotere funktionssignaturer og klassemedlemmer med typeoplysninger; vores typekontrolalgoritme (“type checker”) udleder resten. Typekontrollen er inkrementel, således at selv inden for en enkelt fil kan noget kode konverteres til Hack, mens resten forbliver dynamisk typet. Teknisk set er Hack et “gradvist typet*”* sprog: dynamisk typet kode fungerer problemfrit sammen med statisk typet kode.

I Hacks typesystem har vi indført flere funktioner såsom generiske typer, nullable typer, typealiasing og begrænsninger på typeparametre. Disse nye sprogfunktioner er diskrete, så den kode, du skriver med Hack, vil stadig se ud og føles som det dynamiske sprog, som PHP-programmører er vant til.

Derimod tilføjer Hack yderligere funktioner ud over statisk typekontrol, herunder Collections, lambdaudtryk og håndhævelse på køretid af returtyper og parametertyper.

Collections giver et rent, type-sikkert alternativ til PHP-arrays. Vi har designet dem specifikt til at fungere godt med statisk typebestemmelse og generics. Collections API’et tilbyder mange klassiske funktioner af højere orden såsom map() og filter() for at lette funktionelle programmeringsstile.

Lambda-udtryk giver en kortfattet syntaks til oprettelse af closures. Selv om PHP har closures, kræver det, at programmøren udtrykkeligt navngiver de variabler, som de skal bruge fra omsluttende scopes. Med Hacks lambdaudtryk udleder vi automatisk disse anvendelser, hvilket sparer dig for unødvendigt arbejde. Lambdaudtryk gør det mere bekvemt at udnytte Collections API’et fuldt ud.

Løbtidshåndhævelse af returtyper og parametertyper (herunder skalartyper som int og string) giver sikkerhed ud over det, der kan kontrolleres statisk, mens typeannotationer gradvist tilføjes til en kodebase. Kørselstidshåndhævelse hjælper programmører med at opdage og diagnosticere visse typer problemer lettere, og det hjælper HHVM’s JIT med at producere mere effektiv kode ved at gøre det sikkert at stole på typeannotationer til optimeringsformål.

Instant typekontrol

Under udviklingen går en PHP-programmør typisk hurtigt frem og tilbage mellem kildekoden og browseren. Ingeniører kan iterere så hurtigt, som de har brug for, og teste og justere en oplevelse, indtil den er perfekt.

Traditionelt ville en typekontrol forstyrre dette feedbackloop, da det tager tid at analysere kildekoden. Vi ønskede ikke at bremse PHP-arbejdsgangen, så vi fandt på en ny tilgang for at forene øjeblikkelig feedback med typesikkerhed.

Vores løsning var at arkitektonisere typechecken som en lokal server, der overvåger filsystemet. Serveren opbevarer alle oplysninger om kildekoden i hukommelsen og opdaterer automatisk sig selv, når en fil ændres på disken. Denne fremgangsmåde har givet pote: typechecken kører typisk på mindre end 200 millisekunder og tager sjældent mere end et sekund, hvilket gør den nem at integrere i udviklingsarbejdsgangen uden at indføre en mærkbar forsinkelse.

Kodeoverførsel

Hacks type-sikkerheds- og refaktoriseringsfordele vokser, jo mere den bruges i en kodebase. I forståelse for, at det ville være vanskeligt for noget kode at blive overført fuldstændigt til Hack med det samme, var det vigtigt for os, at Hack blev udviklet på en sådan måde, at det kan eksistere direkte sammen med andre PHP-filer, efterhånden som det indføres gradvist.

Resten af konverteringsprocessen, såsom tilføjelse af typeannotationer og brug af nye sprogfunktioner, kan gøres efter behov for kodebasen. Der kan f.eks. tilføjes en typeannotation til en funktion, men udelades i en anden funktion, selv i den samme fil. Hvis en funktionsparameter eller et klassemedlem ikke har en eksplicit typeannotation, betragter typekontrollen dens type som dynamisk, og den kontrollerer ikke typen af den pågældende værdi.

Inden for Facebook fandt vi ud af, at vores ingeniører satte så stor pris på Hack, at de begyndte at konvertere størstedelen af deres egen kode frivilligt. Med millioner af kodelinjer i vores træ ønskede vi også en form for automatisering, så vi byggede og bruger en række kodemodifikationsværktøjer til at hjælpe processen (som vi frigiver som en del af Hack).

Du skal ikke være bekymret, dit PHP er sikkert!

HVM er stadig en PHP-køringstid, og det har vi til hensigt at holde det sådan. Faktisk arbejder vi hårdt på at nå paritet med PHP-5. En af HHVM’s topprioriteter er at køre uændret PHP-5-kildekode, både af hensyn til fællesskabet og fordi vi er afhængige af PHP-biblioteker fra tredjeparter internt.

HVM er nu en køretid, der understøtter *både* PHP og Hack, så du kan begynde at drage fordel af Hacks nye funktioner trinvis.

Have fun with Hack!

Vi er glade for at open source både Hack og de værktøjer, du kan bruge til automatisk at konvertere din kodebase. Dette er blot det første skridt, og vi er dedikerede til fortsat at udvikle denne software for at gøre udviklingen endnu nemmere for både vores egne ingeniører og det bredere fællesskab. Hacks værdi er *ikke* begrænset til store projekter: med typeoplysninger, gode fejlmeddelelser og hurtig feedback kan små kodebaser også høste fordelene ved Hack.

I næste måned præsenterer vi også sproget på Hack Developer Day på Facebooks campus i Menlo Park, og vi håber at se dig der personligt eller online.

Vi vil meget gerne have din feedback på vores arbejde indtil videre, og vi byder jer alle velkommen til at deltage i HHVM- og Hack-fællesskabet.

Anerkendelser

Der er mange mennesker, der har bidraget til udviklingen af Hack.

Det centrale Hack-team består af Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar og Joshua Van Dyke Watzman.

En særlig tak går til vores tidlige community adopters for at give værdifuld feedback for at gøre sproget bedre: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier og Alexander Mols.

Hack er primært skrevet i OCaml. Vi vil gerne takke Gallium-holdet (INRIA) for udviklingen af OCaml-sproget og Ocsigen-holdet (CNRS – University of Paris Diderot – INRIA) for udviklingen af js_of_ocaml-delen af Ocsigen.

Og selvfølgelig tak til alle andre, der har været med til at gøre Hack til det sprog, det er i dag. Listen er for udtømmende til et blogindlæg, men I ved, hvem I er.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.