Hack: ett nytt programmeringsspråk för HHVM – Facebook Engineering

Har du bråttom? Prova Hack nu: http://hacklang.org/

I dag släpper vi Hack, ett programmeringsspråk som vi utvecklat för HHVM och som fungerar sömlöst med PHP. Hack förenar PHP:s snabba utvecklingscykel med den disciplin som statisk typning ger, samtidigt som det lägger till många funktioner som är vanliga i andra moderna programmeringsspråk.

Vi har använt Hack på Facebook och det har blivit en stor framgång. Under det senaste året har vi migrerat nästan hela vår PHP-kodbas till Hack, tack vare både organisk spridning och ett antal egenutvecklade refaktoriseringsverktyg.

Vi är också stolta över att släppa en öppen källkodsversion av Hack till allmänheten på http://hacklang.org/ som en del av vår HHVM-körtidsplattform, som nu kommer att ha stöd för både Hack och PHP.

Motivation

Varje PHP-programmerare är bekant med vardagliga uppgifter som kan vara knepiga eller besvärliga. Koden ovan är ett bra exempel på ett vanligt misstag där en metod oväntat kan anropas på ett nollobjekt, vilket orsakar ett fel som inte fångas upp förrän vid körning. Ett annat exempel är ett komplext API, där utvecklare kanske har en gedigen förståelse för dess semantik men ändå ägnar tid åt att leta upp banala metodnamn i dokumentationen.

I Facebooks skala – med tusentals ingenjörer som skickar ut ny kod två gånger om dagen – är fördröjningar som dessa ännu mer problematiska. Före Hack hade vi ett enkelt språk med en snabb återkopplingsslinga – men hur kunde vi minska den typ av problem som beskrivs ovan? Kunde tidig felupptäckt samexistera med snabb iteration, samtidigt som vi bevarade vår investering i PHP? Skulle förbättrad kodanalys och introspektion kunna bidra till att göra utvecklarna mer produktiva med hjälp av verktyg som autokomplettering?

Traditionellt sett möjliggör dynamiskt typade språk snabb utveckling, men offrar förmågan att fånga upp fel tidigt och introspektera koden snabbt, särskilt på större kodbaser. Omvänt ger statiskt typade språk mer av ett skyddsnät, men ofta på bekostnad av snabb iteration. Vi trodde att det måste finnas en bra lösning.

Därmed föddes Hack. Vi tror att det erbjuder det bästa av både dynamiskt typade och statiskt typade språk och att det kommer att vara värdefullt för projekt av alla storlekar.

Språket Hack

Hack har djupa rötter i PHP. Faktum är att de flesta PHP-filer redan är giltiga Hack-filer. Vi gjorde ett medvetet val att inte stödja en handfull föråldrade funktioner och funktioner som var oförenliga med statisk typning (t.ex. ”variabla variabler” och funktionen extract()). Vi har också lagt till många nya funktioner som vi tror kommer att bidra till att göra utvecklare mer produktiva.

Vårt främsta tillägg är statisk typning. Vi har utvecklat ett system för att annotera funktionssignaturer och klassmedlemmar med typinformation; vår algoritm för typkontroll (”type checker”) härleder resten. Typkontrollen är inkrementell, vilket innebär att även inom en enskild fil kan viss kod konverteras till Hack medan resten förblir dynamiskt typad. Tekniskt sett är Hack ett ”gradvis typat*”* språk: dynamiskt typad kod samverkar sömlöst med statiskt typad kod.

Inom Hacks typsystem har vi infört flera funktioner som generics, nullable types, type aliasing och begränsningar på typparametrar. Dessa nya språkfunktioner är diskreta, så den kod du skriver med Hack kommer fortfarande att se ut och kännas som det dynamiska språk som PHP-programmerare är vana vid.

Hock lägger Hack dock till ytterligare funktioner utöver statisk typkontroll, inklusive Collections, lambdauttryck och verkställighet i körtid av returtyper och parametertyper.

Collections ger ett rent, typsäkert alternativ till PHP arrays. Vi utformade dem specifikt för att fungera bra med statisk typning och generics. Collections API erbjuder många klassiska funktioner av högre ordning som map() och filter() för att underlätta funktionella programmeringsstilar.

Lambdauttryck ger en kortfattad syntax för att skapa closures. PHP har visserligen closures, men kräver att programmeraren uttryckligen namnger de variabler som de behöver använda från omslutande scopes. Med Hacks lambdauttryck härleder vi automatiskt dessa användningar, vilket sparar dig onödigt arbete. Lambdauttryck gör det bekvämare att dra full nytta av Collections API.

Körning av returtyper och parametertyper (inklusive skalära typer som int och sträng) ger en säkerhet som är större än vad som kan kontrolleras statiskt medan typannotationer gradvis läggs till i en kodbas. Verkställighet i körtid hjälper programmerare att lättare upptäcka och diagnostisera vissa typer av problem, och det hjälper HHVM:s JIT att producera effektivare kod genom att göra det säkert att lita på typannotationer i optimeringssyfte.

Instant typkontroll

Under utvecklingen går en PHP-programmerare vanligtvis snabbt fram och tillbaka mellan källkoden och webbläsaren. Ingenjörer kan iterera så snabbt som de behöver, testa och justera en upplevelse tills den är perfekt.

Traditionellt sett skulle en typkontroll stör denna återkopplingsslinga eftersom det tar tid att analysera källkoden. Vi ville inte bromsa PHP-arbetsflödet, så vi tog fram ett nytt tillvägagångssätt för att förena omedelbar återkoppling med typsäkerhet.

Vår lösning var att bygga upp typkontrollen som en lokal server som bevakar filsystemet. Servern har all information om källkoden i minnet och uppdaterar sig automatiskt när en fil ändras på disken. Detta tillvägagångssätt har gett resultat: typkontrollen körs vanligtvis på mindre än 200 millisekunder och tar sällan mer än en sekund, vilket gör den lätt att integrera i utvecklingsarbetsflödet utan att införa en märkbar fördröjning.

Kodmigrering

Hacks fördelar när det gäller typsäkerhet och refaktorisering växer ju mer den används i en kodbas. Med förståelse för att det skulle vara svårt för viss kod att helt och hållet övergå till Hack direkt, var det viktigt för oss att Hack utvecklas så att det kan samexistera direkt med andra PHP-filer när det introduceras stegvis.

Resten av konverteringsprocessen, som att lägga till typannotationer och använda nya språkfunktioner, kan göras på det sätt som är lämpligt för kodbasen. Till exempel kan en typannotation läggas till för en funktion men utelämnas för en annan funktion, även i samma fil. Om en funktionsparameter eller en klassmedlem inte har en explicit typannotation anser typkontrollen att dess typ är dynamisk och kontrollerar inte typen av det värdet.

Inom Facebook upptäckte vi att våra ingenjörer uppskattade Hack tillräckligt mycket för att de började konvertera majoriteten av sin egen kod frivilligt. Med miljontals rader kod i vårt träd ville vi också ha någon form av automatisering, så vi byggde och använder ett antal kodmodifieringsverktyg för att underlätta processen (som vi släpper som en del av Hack).

Oroa dig inte, din PHP är säker!

HVM är fortfarande en PHP-körningstid, och vi har för avsikt att låta det fortsätta vara så. Faktum är att vi arbetar hårt för att nå paritet med PHP-5. En av HHVM:s högsta prioriteringar är att köra oförändrad PHP-5-källkod, både för gemenskapens skull och för att vi förlitar oss på PHP-bibliotek från tredje part internt.

HVM är nu en körtid som har stöd för *både* PHP och Hack, så du kan börja dra nytta av Hacks nya funktioner stegvis.

Att ha roligt med Hack!

Vi är glada att kunna öppna källkoden för både Hack och de verktyg som du kan använda för att automatiskt konvertera din kodbas. Detta är bara det första steget, och vi är fast beslutna att fortsätta att utveckla denna programvara för att göra utvecklingen ännu enklare för både våra egna ingenjörer och den bredare gemenskapen. Hacks värde är *inte* begränsat till stora projekt: med typinformation, bra felmeddelanden och snabb återkoppling kan även små kodbaser dra nytta av Hack.

Nästa månad kommer vi också att presentera språket på Hack Developer Day på Facebooks campus i Menlo Park, och vi hoppas att vi får träffa dig där, personligen eller på nätet.

Vi vill gärna ha din återkoppling på vårt arbete så här långt, och vi välkomnar alla till att delta i HHVM och Hack community.

Acknowledgements

Det finns många människor som har bidragit till utvecklingen av Hack.

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

Ett särskilt tack går till våra tidiga community adopters för värdefull feedback för att göra språket bättre: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier och Alexander Mols.

Hack är huvudsakligen skrivet i OCaml. Vi vill tacka Gallium-teamet (INRIA) för utvecklingen av OCaml-språket och Ocsigen-teamet (CNRS – University of Paris Diderot – INRIA) för utvecklingen av js_of_ocaml-delen av Ocsigen.

Och, naturligtvis, tack till alla andra som har hjälpt till att göra Hack till det språk det är idag. Listan är för uttömmande för ett blogginlägg, men ni vet vilka ni är.

Lämna ett svar

Din e-postadress kommer inte publiceras.