Acest articol e în strânsă legătură cu cel despre maşina virtuală HipHop, publicat în numărul 21 al revistei. Atunci când Mark Zuckerberg a scris primele linii de cod ale Facebook-ului, a fost nevoit să aleagă limbajul de programare în care să dezvolte noua reţea de socializare. A ales PHP-ul pentru că, după cum ştim cu toţii, acesta are un ciclu de dezvoltare foarte rapid: faci o modificare, salvezi fişierul, apeşi F5 în browser şi vezi modificarea instantaneu. Acest lucru e posibil pentru că nu există un pas de compilare pe care programatorul trebuie să-l facă şi pentru că PHP-ul e un limbaj dinamic (nu obligă declararea tipurilor variabilelor).
Toate acestea sunt în contrast cu limbajele bazate pe un model static, cum ar fi Java, C#, C++ etc..În aceste cazuri, compilarea e un pas obligatoriu şi, în cazul proiectelor mari, nu unul care să dureze puţin.
În schimb, modelul static al acestor limbaje oferă niște avantaje foarte mari: bug-urile se pot detecta extrem de repede şi informaţiile statice despre tipuri oferă un fel de documentare automată a codului.
Echipa de ingineri care dezvoltă partea front-end a Facebook-ului a crescut de la 80 de ingineri în 2008 până la 1000 în 2014. Iar lipsa scalabilităţii unei astfel de echipe, în combinaţie cu faptul că, la Facebook, se introduce cod în producţie de două ori pe zi, are drept consecință foarte mult cod şi foarte mult potenţial pentru probleme. Aşa că echipa de ingineri de la Facebook a decis să împrumute o parte din avantajele celeilalte lumi (cea a limbajelor statice) pentru a reduce o parte din riscurile asociate unei echipe atât de mare de programatori.
Din această dorinţă s-a născut limbajul Hack, un limbaj hibrid care face legătura între cele două lumi.
După cum menționam mai sus, Hack este un limbaj hibrid care aduce în lumea PHP-ului (un limbaj dinamic) avantajele unui model static. Nu este nimic altceva decât o extensie sintactică a PHP-ului.
Hack-ul rulează momentan doar pe maşina virtuală HipHop, de la versiunea 3.0 şi în sus a acesteia. A fost făcut open source în Martie 2014.
Un aspect important este faptul că, dacă ştii PHP, atunci ştii Hack.
Există două caracteristici foarte importante ale Hack-ului care i-a asigurat adopţia în cadrul Facebook-ului şi, poate în viitor, şi în cadrul unor aplicaţii terţe:
Hack-ul vine cu nişte facilităţi interesante în plus față de ceea ce ceea ce ofera deja PHP-ul. Pentru a vedea detalii şi sintaxa a ceea ce se prezintă mai jos, vedeţi documentaţia oficială a limbajului.
De departe, aceasta este cea mai importantă facilitate. Permite specificarea tipurilor de date în cadrul parametrilor de funcţii, tipului returnat de o funcţie şi câmpurilor claselor. Tipurile variabilelor din codul propriu-zis nu pot fi declarate; în schimb, sunt “ghicite” de către maşina virtuală.
Mulţi programatori specifică aceste informaţii sub formă de comentarii. Hack-ul formalizează această informaţie.
Tipurile de date ce se pot specifica sunt în general cele care pot fi specificate şi în cadrul altor limbaje statice: tipuri primitive, şiruri de caractere, nume de clase, “void”, “this” etc.
Astfel se oferă avantajul detectării mai rapide a bug-urilor. De asemenea, având în vedere existenţa în acest fel a informaţiei statice în plus, compilatorul JIT din cadrul maşinii virtuale va putea intui mai bine ce căi de execuţie vor fi traversate mai des. Acest aspect demonstrează performanţa crescută.
Multe limbaje au această calitate. În Hack, generics-urile vin ca o întărire şi mai puternică a conceptului de anotări descrisă mai sus. Implementarea şi sintaxa lor este mai simplă şi mai limitată decât în cazul limbajelor Java şi C# de exemplu. În schimb, în Hack se permite folosirea tipurilor de date primitive şi chiar a instanţelor de obiecte pentru a specifica tipul de date generic.
Există totuşi nişte cazuri speciale de care trebuie ţinut cont în legătura cu această facilitate.
La fel cum cele mai multe limbaje statice oferă această funcţionalitate, aceasta e binevenită şi în Hack. Cele mai importante clase din acest framework sunt “Map”, “Vector” şi “Set”, fiecare dintre acestea având un corespondent care oferă imutabilitate.
Codul PHP obişnuit este de obicei împânzit cu array-uri. Dacă, în schimb, se vor folosi aceste clase, atunci codul va deveni mai clar şi, în unele cazuri, se vor vedea şi sporuri de performanţă.
PHP-ul nu are suport pentru mai multe fire de execuţie. Însă Hack introduce un foarte primitiv suport pentru această facilitate.
Acestea sunt similare cu closure-urile deja existente în PHP, însă elimină o parte din limitări şi oferă o mai mare flexibilitate. Sintaxa acestora este asemănătoare cu cea pe care o putem vedea în Java 8.
Aceasta e o extensie opţională a Hack-ului care permite folosirea de blocuri XML/HTML ca pe nişte elemente standard de sintaxă. În acest fel se uşurează foarte mult munca în cadrul codului care conţine logică şi elemente specifice templating-ului.
Hack oferă şi alte facilităţi minore demne de luat în calcul. De asemenea, o parte din elementele de sintaxă ale PHP-ului despre care se ştie că sunt ineficient sau rar folosite, sunt dezactivate, cum ar fi de exemplu operatorul @
, operaţiunea goto
, globalele (global $x
) şi multe altele. Prin urmare, acest nou aspect luat în considerare va forţa programatorul să urmeze bune practici de programare.
Mai jos puteți vedea o bucată de cod care exemplifică multe din facilitățile prezentate mai sus. Puteți vedea cum sunt specificate anotarile de tipuri, cum e folosită una din clasele din framework-ul colecțiilor, un exemplu de tipuri generice și o expresie lambda simplă:
class MyExampleClass {
public int $number;
public CustomClass $myObject;
private string $name;
private array $stuff;
private MyBag $container;
function doStuff(MyBag $container, ?bool $x) : string {
//immutable Map
$map = ImmMap {
‹A› => $container->getA(),
‹B› => $container->getB(),
};
if ($map->get(‹A›) == $container->getA()) {
//error here because $map is immutable
$map->set(‹C›, $container->getC());
}
//$x is of type ?bool, which means:
//a). it›s of type boolean
//b). can also be null
if (! is_null($x) && $x) {
//lambda expression
//and alternative/classic syntax for
//accessing map elements
$result = $r ==> $r + $map[‹A›] + $map[‹B›];
} else {
$result = 0;
}
//error here because function›s return type is string
return $result;
}
}
Maşina virtuală HipHop vine împreună cu niște unelte foarte utile:
Cele necesare transformării unui codebase PHP într-unul Hack. Acestea sunt relativ simplu de utilizat şi automatizează cea mai mare parte din proces, astfel încât programatorului îi va rămâne o cantitate minimală de muncă. În schimb, pe un codebase foarte mare, acest proces poate să dureze. De exemplu, pentru a transforma codul sursă a Facebook-ului (aproximativ 25 de milioane de linii), a fost nevoie de consumul a 10 GB RAM și un timp de procesare de 12 ore. În majoritatea cazurilor însă, nu ar trebui să depăşească câteva minute.
Erorile raportate de typechecker sunt doar legate de anotările de tip. Timpul de răspuns al acestuia este foarte rapid datorită monitorizării constante a sistemului de fişiere.
Acest typechecker are în schimb o serie de limitări:
Hack-ul este un suflu nou adus unui limbaj a cărui dezvoltare a cam stagnat în ultimii ani. Hibriditatea dată de adăugarea unui model static peste un limbaj dinamic este un concept interesant pe care cu siguranță îl vom mai vedea în următorii ani.
Personal, sunt impresionat de eleganța cu care facilitățile Hack-ului au fost implementate și îmbinate cu sintaxa existentă a PHP-ului. Sunt multe aspecte (în special sintactice) pe care nu le-am atins. Așa că vă invit să le explorați pe cont propriu, cu speranța că acest articol v-a trezit curiozitatea de a face asta.
de Sorin Pânca