Hack: nový programovací jazyk pro HHVM – Facebook Engineering

Spěcháte? Vyzkoušejte Hack hned teď: http://hacklang.org/

Dnes vydáváme Hack, programovací jazyk vyvinutý pro HHVM, který bez problémů spolupracuje s PHP. Hack slaďuje rychlý vývojový cyklus jazyka PHP s disciplínou, kterou poskytuje statické typování, a zároveň přidává mnoho funkcí, které se běžně vyskytují v jiných moderních programovacích jazycích.

Hack jsme nasadili ve společnosti Facebook a sklidil velký úspěch. Za poslední rok jsme na Hack převedli téměř celou naši kódovou základnu PHP, a to jak díky organickému přijetí, tak díky řadě domácích refaktorizačních nástrojů.

Jsme také hrdí na to, že jsme uvolnili open source verzi Hack pro veřejnost http://hacklang.org/jako součást naší runtime platformy HHVM, která nyní bude podporovat jak Hack, tak PHP.

Motivace

Každý programátor PHP zná každodenní úkoly, které mohou být složité nebo těžkopádné. Výše uvedený kód je skvělým příkladem běžné chyby, kdy může být metoda neočekávaně zavolána na nulovém objektu, což způsobí chybu, která bude zachycena až za běhu. Dalším příkladem je složité rozhraní API, u kterého mohou vývojáři dobře rozumět jeho sémantice, ale přesto tráví čas hledáním prozaických názvů metod v dokumentaci.

V měřítku Facebooku – s tisíci inženýry dodávajícími nový kód dvakrát denně – jsou taková zpomalení ještě problematičtější. Před Hackem jsme měli jednoduchý jazyk s rychlou zpětnou vazbou – ale jak jsme mohli zmírnit výše popsané druhy problémů? Mohla by včasná detekce chyb koexistovat s rychlou iterací, a to vše při zachování naší investice do jazyka PHP? Mohla by lepší analýza a introspekce kódu pomoci zvýšit produktivitu vývojářů pomocí nástrojů, jako je automatické doplňování?

Dynamicky typované jazyky tradičně umožňují rychlý vývoj, ale obětují schopnost včasného zachycení chyb a rychlé introspekce kódu, zejména u větších kódových bází. Naopak staticky typované jazyky poskytují větší záchrannou síť, ale často za cenu rychlé iterace. Věřili jsme, že musí existovat nějaký sladký bod.

Tak se zrodil Hack. Věříme, že nabízí to nejlepší z dynamicky typovaných i staticky typovaných jazyků a že bude cenný pro projekty všech velikostí.

Jazyk Hack

Hack má hluboké kořeny v PHP. Ve skutečnosti je většina souborů PHP již platnými soubory jazyka Hack. Vědomě jsme se rozhodli nepodporovat hrstku zastaralých funkcí a vlastností, které byly neslučitelné se statickým typováním (např. „proměnné proměnné“ a funkce extract()). Přidali jsme také mnoho nových funkcí, o kterých věříme, že pomohou zvýšit produktivitu vývojářů.

Naším hlavním přírůstkem je statické typování. Vyvinuli jsme systém pro anotování signatur funkcí a členů tříd typovými informacemi; zbytek odvodí náš algoritmus pro kontrolu typu („type checker“). Typová kontrola je inkrementální, takže i v rámci jednoho souboru lze část kódu převést na Hack, zatímco zbytek zůstává dynamicky typovaný. Technicky vzato je Hack „postupně typovaný*“* jazyk: dynamicky typovaný kód bezproblémově spolupracuje se staticky typovaným kódem.

V rámci typového systému Hack jsme zavedli několik funkcí, jako jsou generika, nulovatelné typy, aliasing typů a omezení na typové parametry. Tyto nové vlastnosti jazyka jsou nenápadné, takže kód psaný pomocí Hacku bude stále vypadat a působit jako dynamický jazyk, na který jsou programátoři PHP zvyklí.

Hack však přidává další funkce nad rámec statické kontroly typů, včetně kolekcí, lambda výrazů a vynucování návratových typů a typů parametrů za běhu.

Kolekce poskytují čistou, typově bezpečnou alternativu k polím PHP. Navrhli jsme je speciálně tak, aby dobře spolupracovaly se statickým typováním a generikami. API Collections nabízí mnoho klasických funkcí vyššího řádu, jako jsou map() a filter(), které usnadňují funkcionální styly programování.

Výrazy lambda poskytují stručnou syntaxi pro vytváření uzávěrů. Jazyk PHP sice uzávěry má, ale vyžaduje, aby programátor explicitně pojmenoval proměnné, které potřebuje použít z obklopujících rozsahů. Pomocí lambda výrazů Hack tato použití automaticky odvozujeme, což vám ušetří zbytečnou práci. Lambda výrazy umožňují pohodlněji plně využívat rozhraní API Collections.

Vynucování návratových typů a typů parametrů za běhu (včetně skalárních typů jako int a string) poskytuje bezpečnost nad rámec toho, co lze kontrolovat staticky, zatímco se do kódové základny postupně přidávají typové anotace. Vynucování za běhu pomáhá programátorům snadněji odhalit a diagnostikovat určité druhy problémů a pomáhá JIT HHVM vytvářet efektivnější kód tím, že umožňuje bezpečně důvěřovat typovým anotacím pro účely optimalizace.

Instantní kontrola typů

Během vývoje programátor PHP obvykle rychle přechází mezi zdrojovým kódem a prohlížečem. Inženýři mohou iterovat tak rychle, jak potřebují, testovat a ladit prostředí, dokud není dokonalé.

Tradičně by kontrola typů tuto smyčku zpětné vazby narušila, protože analýza zdrojového kódu vyžaduje čas. Nechtěli jsme zpomalovat pracovní postup PHP, a proto jsme přišli s novým přístupem, jak sladit okamžitou zpětnou vazbu s typovou bezpečností.

Naším řešením byla architektura kontroly typů jako lokálního serveru, který sleduje souborový systém. Server uchovává všechny informace o zdrojovém kódu v paměti a automaticky se aktualizuje, když se soubor na disku změní. Tento přístup se vyplatil: kontrola typů se obvykle spustí za méně než 200 milisekund a zřídkakdy trvá déle než sekundu, takže ji lze snadno začlenit do pracovního postupu vývoje bez znatelného zpoždění.

Migrace kódu

Přínos kontroly typů a refaktorizace Hacku roste, čím více se v rámci kódové základny používá. Chápeme, že pro některé kódy by bylo obtížné přejít kompletně na Hack hned, proto pro nás bylo důležité, aby byl Hack vyvinut tak, aby mohl koexistovat přímo s ostatními soubory PHP při jeho postupném zavádění.

Zbytek procesu převodu, jako je přidávání typových anotací a používání nových vlastností jazyka, lze provádět podle potřeby dané kódové základny. Například lze přidat typovou anotaci pro jednu funkci, ale vynechat jinou funkci, a to i ve stejném souboru. Pokud parametr funkce nebo člen třídy nemá explicitní typovou anotaci, kontrola typu považuje jeho typ za dynamický a typ této hodnoty nekontroluje.

Ve společnosti Facebook jsme zjistili, že naši inženýři ocenili Hack natolik, že začali dobrovolně převádět většinu vlastního kódu. Vzhledem k milionům řádků kódu v našem stromu jsme také chtěli nějakou formu automatizace, takže jsme vytvořili a používáme řadu nástrojů pro úpravu kódu, které tomuto procesu pomáhají (a které uvolňujeme jako součást Hacku).

Nebojte se, vaše PHP je v bezpečí!

HHVM je stále runtime PHP a hodláme to tak zachovat. Ve skutečnosti usilovně pracujeme na dosažení parity s PHP-5. Jednou z hlavních priorit HHVM je spouštět nemodifikovaný zdrojový kód PHP-5, a to jak kvůli komunitě, tak proto, že interně spoléháme na knihovny PHP třetích stran.

HHVM je nyní runtime, který podporuje *obě* verze PHP a Hack, takže můžete začít postupně využívat nové funkce Hacku.

Užívejte si s Hackem!

Jsme rádi, že můžeme otevřít zdrojový kód Hacku i nástroje, které můžete použít k automatickému převodu své kódové základny. Je to jen první krok a jsme odhodláni pokračovat ve vývoji tohoto softwaru, abychom ještě více usnadnili vývoj jak našim vlastním inženýrům, tak širší komunitě. Hodnota Hacku se *neomezuje* jen na velké projekty: díky informacím o typech, dobrým chybovým hlášením a rychlé zpětné vazbě mohou výhody Hacku využívat i malé kódové základny.

Příští měsíc jazyk představíme také na Hack Developer Day v kampusu Facebooku v Menlo Parku a doufáme, že se tam uvidíme osobně nebo online.

Budeme rádi, když nám poskytnete zpětnou vazbu na naši dosavadní práci, a všechny vás uvítáme, když se zapojíte do komunity HHVM a Hack.

Poděkování

Na vývoji Hack se podílelo mnoho lidí.

Jádro týmu Hack tvoří Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar a Joshua Van Dyke Watzman.

Zvláštní poděkování patří našim prvním osvojitelům z řad komunity za poskytnutí cenné zpětné vazby, která přispěla k vylepšení jazyka: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier a Alexander Mols.

Hack je napsán především v jazyce OCaml. Rádi bychom poděkovali týmu Gallium (INRIA) za vývoj jazyka OCaml a týmu Ocsigen (CNRS – University of Paris Diderot – INRIA) za vývoj části js_of_ocaml v Ocsigenu.

A samozřejmě děkujeme všem ostatním, kteří pomohli vytvořit jazyk Hack takový, jaký je dnes. Seznam je příliš vyčerpávající na příspěvek na blogu, ale vy víte, kdo jste.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.