Hack: egy új programozási nyelv a HHVM-hez – Facebook Engineering

Sietsz? Próbáld ki a Hacket most: http://hacklang.org/

A mai napon kiadjuk a Hacket, a HHVM számára kifejlesztett programozási nyelvet, amely zökkenőmentesen együttműködik a PHP-vel. A Hack összehangolja a PHP gyors fejlesztési ciklusát a statikus tipizálás által biztosított fegyelemmel, miközben számos, más modern programozási nyelvekben általánosan megtalálható funkciót ad hozzá.

A Hacket a Facebooknál telepítettük, és nagy sikert aratott. Az elmúlt egy év során szinte a teljes PHP kódbázisunkat áttettük a Hackre, köszönhetően mind a szerves elfogadásnak, mind a saját fejlesztésű refaktorálási eszközöknek.

Azzal is büszkék vagyunk, hogy a Hack nyílt forráskódú változatát a nyilvánosság számára http://hacklang.org/ a HHVM futtatási platformunk részeként adjuk ki, amely mostantól a Hacket és a PHP-t is támogatja.

Motiváció

Minden PHP-programozó ismeri a trükkös vagy nehézkes mindennapi feladatokat. A fenti kód remek példa egy gyakori hibára, amikor egy metódus váratlanul meghívásra kerülhet egy null objektumon, ami olyan hibát okoz, amelyet futásidőig nem észlelünk. Egy másik példa egy összetett API, amelynek szemantikáját a fejlesztők ugyan jól ismerik, de mégis időt töltenek azzal, hogy a dokumentációban banális metódusnevek utánanézzenek.

A Facebook léptékében – ahol több ezer mérnök naponta kétszer küld új kódot – az ilyen lassulások még problémásabbak. A Hack előtt volt egy egyszerű nyelvünk, gyors visszacsatolási hurokkal – de hogyan tudtuk enyhíteni a fent leírt problémák fajtáit? A korai hibafelismerés és a gyors iteráció együtt tudott-e működni, miközben megőriztük a PHP-ba való befektetésünket? A jobb kódelemzés és introspekció segíthetne a fejlesztők produktívabbá tételében az olyan eszközökkel, mint az automatikus kitöltés?

A dinamikusan tipizált nyelvek hagyományosan gyors fejlesztést tesznek lehetővé, de feláldozzák a korai hibakeresés és a kód gyors introspekciójának képességét, különösen a nagyobb kódbázisok esetében. Ezzel szemben a statikusan tipizált nyelvek nagyobb biztonsági hálót nyújtanak, de gyakran a gyors iteráció árán. Úgy gondoltuk, hogy kell lennie egy jó pontnak.

Így született meg a Hack. Úgy véljük, hogy a dinamikusan tipizált és a statikusan tipizált nyelvek legjobb tulajdonságait kínálja, és hogy minden méretű projekt számára értékes lesz.

A Hack nyelv

A Hack mélyen a PHP-ben gyökerezik. Valójában a legtöbb PHP fájl már érvényes Hack fájl. Tudatosan döntöttünk úgy, hogy nem támogatunk egy maroknyi elavult függvényt és funkciót, amelyek nem kompatibilisek a statikus tipizálással (pl. a “változóváltozók” és az extract() függvény). Emellett számos új funkciót adtunk hozzá, amelyekről úgy gondoljuk, hogy segítenek a fejlesztők produktívabbá tételében.

A fő újításunk a statikus tipizálás. Kifejlesztettünk egy rendszert a függvényaláírások és az osztálytagok típusinformációkkal való megjegyzésére; a típusellenőrző algoritmusunk (a “típusellenőrző”) a többit kikövetkezteti. A típusellenőrzés inkrementális, így akár egyetlen fájlon belül is átalakítható néhány kód Hackre, míg a többi dinamikusan tipizált marad. Technikailag a Hack egy “fokozatosan tipizált*”* nyelv: a dinamikusan tipizált kód zökkenőmentesen együttműködik a statikusan tipizált kóddal.

A Hack típusrendszerében számos jellemzőt vezettünk be, mint például a generikus, nullázható típusok, a típus aliasing és a típusparaméterekre vonatkozó korlátozások. Ezek az új nyelvi jellemzők nem feltűnőek, így a Hackkel írt kód továbbra is úgy fog kinézni, mint a PHP-programozók által megszokott dinamikus nyelv.

A Hack azonban a statikus típusellenőrzésen túl további funkciókat is tartalmaz, beleértve a gyűjtemények, lambda-kifejezések, valamint a visszatérési típusok és paramétertípusok futásidejű érvényesítését.

A gyűjtemények a PHP tömbök tiszta, típusbiztos alternatíváját jelentik. Kifejezetten úgy terveztük őket, hogy jól működjenek a statikus tipizálással és a generikusokkal. A Collections API számos klasszikus magasabb rendű függvényt kínál, mint például a map() és a filter() a funkcionális programozási stílusok megkönnyítése érdekében.

A lambda kifejezések tömör szintaxist biztosítanak a lezárások létrehozásához. Bár a PHP rendelkezik lezárásokkal, a programozónak explicit módon meg kell neveznie azokat a változókat, amelyeket a körülvevő hatókörökből kell használnia. A Hack lambda-kifejezésekkel automatikusan kikövetkeztetjük ezeket a felhasználásokat, így felesleges munkát spórolunk meg. A lambda kifejezések kényelmesebbé teszik a Collections API teljes körű kihasználását.

A visszatérési és paramétertípusok (beleértve a skalár típusokat, mint az int és a string) futásidejű kényszerítése nagyobb biztonságot nyújt, mint ami statikusan ellenőrizhető, miközben a típusjegyzeteket fokozatosan adjuk hozzá a kódbázishoz. A futásidejű kényszerítés segít a programozóknak könnyebben felismerni és diagnosztizálni bizonyos típusú problémákat, és segít a HHVM JIT-jének hatékonyabb kódot előállítani azáltal, hogy optimalizálási célokból biztonságosan megbízhatunk a típusmegjegyzésekben.

Instantaneous type checking

A fejlesztés során egy PHP-programozó jellemzően gyorsan váltogatja a forráskódot és a böngészőt. A mérnökök olyan gyorsan iterálhatnak, amilyen gyorsan csak kell, tesztelve és hangolva egy élményt, amíg az tökéletes nem lesz.

Hagyományosan egy típusellenőrzés megszakítaná ezt a visszacsatolási kört, mivel időbe telik a forráskód elemzése. Nem akartuk lelassítani a PHP munkafolyamatát, ezért új megközelítéssel álltunk elő, hogy az azonnali visszajelzést összeegyeztetjük a típusbiztonsággal.

A megoldásunk az volt, hogy a típusellenőrzőt egy helyi kiszolgálónak terveztük, amely a fájlrendszert figyeli. A szerver a forráskóddal kapcsolatos összes információt a memóriában tartja, és automatikusan frissíti magát, amikor egy fájl változik a lemezen. Ez a megközelítés kifizetődött: a típusellenőrző általában kevesebb mint 200 milliszekundum alatt fut, és ritkán vesz igénybe egy másodpercnél többet, így könnyen integrálható a fejlesztési munkafolyamatba anélkül, hogy észrevehető késedelmet okozna.

Kódmigráció

A Hack típusbiztonsági és refaktorálási előnyei annál nagyobbak, minél többet használják egy kódbázison belül. Megértve, hogy bizonyos kódokat nehéz lenne azonnal teljesen átállítani a Hackre, fontos volt számunkra, hogy a Hacket úgy fejlesszük, hogy a fokozatos bevezetés során közvetlenül együtt tudjon létezni más PHP-fájlokkal.

A konverziós folyamat többi része, például a típusjegyzetek hozzáadása és az új nyelvi funkciók használata a kódbázisnak megfelelően történhet. Például egy típusmegjelölés hozzáadható egy függvényhez, de elhagyható egy másik függvénynél, akár ugyanabban a fájlban is. Ha egy függvényparaméter vagy osztálytag nem rendelkezik explicit típusjelöléssel, a típusellenőrző dinamikusnak tekinti a típusát, és nem ellenőrzi az adott érték típusát.

A Facebookon belül azt tapasztaltuk, hogy a mérnökeink eléggé értékelték a Hacket ahhoz, hogy saját kódjuk nagy részét önként kezdték el átalakítani. Mivel több millió sornyi kód van a fánkban, szerettünk volna valamilyen formában automatizálni is, ezért számos kódmódosító eszközt készítettünk és használunk a folyamat segítésére (amelyeket a Hack részeként adunk ki).

Ne aggódj, a PHP-d biztonságban van!

A HHVM még mindig egy PHP-futtató, és szándékunkban áll, hogy ez így is maradjon. Valójában keményen dolgozunk azon, hogy elérjük a PHP-5-tel való paritást. A HHVM egyik legfontosabb prioritása, hogy változatlan PHP-5 forráskódot futtasson, mind a közösség miatt, mind pedig azért, mert belsőleg harmadik féltől származó PHP könyvtárakra támaszkodunk.

A HHVM most már egy olyan futtató, amely *mind a PHP-t, mind a Hack-et támogatja, így fokozatosan kezdheti el kihasználni a Hack új funkcióit.

Jó szórakozást a Hackkel!

Örömmel nyitjuk meg a Hack és a kódbázis automatikus átalakításához használható eszközök forrását. Ez csak az első lépés, és elkötelezettek vagyunk a szoftver folyamatos fejlesztése iránt, hogy még könnyebbé tegyük a fejlesztést mind a saját mérnökeink, mind a szélesebb közösség számára. A Hack értéke *nem* korlátozódik a nagy projektekre: típusinformációkkal, jó hibaüzenetekkel és gyors visszajelzéssel a kisebb kódbázisok is élvezhetik a Hack előnyeit.

A jövő hónapban a Facebook menlo parki campusán megrendezésre kerülő Hack Developer Day-en is bemutatjuk a nyelvet, és reméljük, hogy ott találkozunk személyesen vagy online.

Örülnénk, ha visszajelzést kapnánk az eddigi munkánkról, és mindenkit szívesen látunk a HHVM és a Hack közösségben.

Megköszönések

A Hack fejlesztéséhez sokan járultak hozzá.

A Hack alapcsapatát Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar és Joshua Van Dyke Watzman alkotják.

Külön köszönet illeti a közösség korai alkalmazóit, akik értékes visszajelzéseket adtak a nyelv jobbá tételéhez: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier és Alexander Mols.

A Hack elsősorban OCaml nyelven íródott. Szeretnénk köszönetet mondani a Gallium csapatnak (INRIA) az OCaml nyelv fejlesztéséért, és az Ocsigen csapatnak (CNRS – University of Paris Diderot – INRIA) az Ocsigen js_of_ocaml részének fejlesztéséért.

És természetesen köszönet mindenkinek, aki segített abban, hogy a Hack azzá a nyelvvé váljon, ami ma. A lista túl kimerítő egy blogbejegyzéshez, de tudjátok, kik vagytok.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.