Hack : un nouveau langage de programmation pour HHVM – Ingénierie de Facebook

Plus pressé ? Essayez Hack maintenant : http://hacklang.org/

Aujourd’hui, nous publions Hack, un langage de programmation que nous avons développé pour HHVM et qui interagit de manière transparente avec PHP. Hack concilie le cycle de développement rapide de PHP avec la discipline fournie par le typage statique, tout en ajoutant de nombreuses fonctionnalités que l’on trouve couramment dans d’autres langages de programmation modernes.

Nous avons déployé Hack chez Facebook et il a rencontré un grand succès. Au cours de la dernière année, nous avons migré la quasi-totalité de notre base de code PHP vers Hack, grâce à la fois à une adoption organique et à un certain nombre d’outils de refactoring maison.

Nous sommes également fiers de publier une version open source de Hack au public à http://hacklang.org/ dans le cadre de notre plateforme d’exécution HHVM, qui supportera désormais à la fois Hack et PHP.

Motivation

Chaque programmeur PHP est familier avec des tâches quotidiennes qui peuvent être délicates ou encombrantes. Le code ci-dessus est un excellent exemple d’une erreur courante où une méthode pourrait être appelée de manière inattendue sur un objet nul, provoquant une erreur qui ne serait pas attrapée jusqu’à l’exécution. Un autre exemple est une API complexe, où les développeurs peuvent avoir une solide compréhension de sa sémantique, mais passent encore du temps à chercher des noms de méthodes banales dans la documentation.

À l’échelle de Facebook – avec des milliers d’ingénieurs expédiant du nouveau code deux fois par jour – les ralentissements comme ceux-ci sont encore plus problématiques. Avant Hack, nous avions un langage simple avec une boucle de rétroaction rapide – mais comment pouvions-nous atténuer le genre de problèmes décrits ci-dessus ? La détection précoce des erreurs pouvait-elle coexister avec une itération rapide, tout en préservant notre investissement dans PHP ? L’amélioration de l’analyse et de l’introspection du code pourrait-elle contribuer à rendre les développeurs plus productifs grâce à des outils tels que l’auto-complétion ?

Traditionnellement, les langages typés dynamiquement permettent un développement rapide mais sacrifient la capacité à détecter les erreurs précocement et à introspecter le code rapidement, en particulier sur les bases de code plus importantes. À l’inverse, les langages typés statiquement fournissent davantage un filet de sécurité, mais souvent au prix d’une itération rapide. Nous avons pensé qu’il devait y avoir un juste milieu.

C’est ainsi que Hack est né. Nous pensons qu’il offre le meilleur des langages typés dynamiquement et statiquement, et qu’il sera précieux pour les projets de toutes tailles.

Le langage Hack

Hack a des racines profondes dans PHP. En fait, la plupart des fichiers PHP sont déjà des fichiers Hack valides. Nous avons fait le choix délibéré de ne pas prendre en charge une poignée de fonctions et de fonctionnalités dépréciées qui étaient incompatibles avec le typage statique (par exemple, les « variables variables » et la fonction extract()). Nous avons également ajouté de nombreuses nouvelles fonctionnalités qui, selon nous, aideront à rendre les développeurs plus productifs.

Notre principal ajout concerne le typage statique. Nous avons développé un système pour annoter les signatures de fonction et les membres de classe avec des informations de type ; notre algorithme de vérification de type (le « vérificateur de type ») infère le reste. La vérification de type est incrémentale, de sorte que même dans un seul fichier, une partie du code peut être convertie en Hack tandis que le reste reste reste typée dynamiquement. Techniquement parlant, Hack est un langage « graduellement typé* »* : le code dynamiquement typé interagit de manière transparente avec le code statiquement typé.

A l’intérieur du système de types de Hack, nous avons introduit plusieurs fonctionnalités telles que les génériques, les types nullables, l’aliasing de type et les contraintes sur les paramètres de type. Ces nouvelles fonctionnalités du langage sont discrètes, donc le code que vous écrivez avec Hack ressemblera toujours au langage dynamique auquel les programmeurs PHP sont habitués.

Cependant, Hack ajoute des fonctionnalités supplémentaires au-delà de la vérification statique des types, y compris les Collections, les expressions lambda, et l’application à l’exécution des types de retour et des types de paramètres.

Les Collections fournissent une alternative propre et sûre en termes de types aux tableaux PHP. Nous les avons conçus spécifiquement pour bien fonctionner avec le typage statique et les génériques. L’API Collections offre de nombreuses fonctions classiques d’ordre supérieur telles que map() et filter() pour faciliter les styles de programmation fonctionnelle.

Les expressions Lambda donnent une syntaxe concise pour créer des closures. Bien que PHP dispose de closures, il exige du programmeur qu’il nomme explicitement les variables qu’il doit utiliser à partir de scopes englobants. Avec les expressions lambda de Hack, nous déduisons automatiquement ces utilisations, ce qui vous évite un travail inutile. Les expressions lambda permettent de tirer pleinement parti de l’API Collections.

L’application en cours d’exécution des types de retour et des types de paramètres (y compris les types scalaires tels que int et string) offre une sécurité supérieure à ce qui peut être vérifié statiquement pendant que les annotations de type sont progressivement ajoutées à une base de code. La mise en application à l’exécution aide les programmeurs à détecter et à diagnostiquer plus facilement certains types de problèmes, et elle aide le JIT de HHVM à produire un code plus efficace en rendant sûre la confiance dans les annotations de type à des fins d’optimisation.

Vérification instantanée des types

Pendant le développement, un programmeur PHP fait généralement des allers-retours rapides entre le code source et le navigateur. Les ingénieurs peuvent itérer aussi rapidement qu’ils en ont besoin, en testant et en réglant une expérience jusqu’à ce qu’elle soit parfaite.

Traditionnellement, un vérificateur de type perturberait cette boucle de rétroaction car il prend du temps pour analyser le code source. Nous ne voulions pas ralentir le flux de travail de PHP, nous avons donc proposé une nouvelle approche pour concilier la rétroaction instantanée et la sécurité des types.

Notre solution a consisté à architecturer le vérificateur de types comme un serveur local qui surveille le système de fichiers. Le serveur garde toutes les informations sur le code source en mémoire et se met automatiquement à jour lorsqu’un fichier change sur le disque. Cette approche s’est avérée payante : le vérificateur de types s’exécute généralement en moins de 200 millisecondes et prend rarement plus d’une seconde, ce qui facilite son intégration dans le flux de développement sans introduire de retard notable.

Migration du code

Les avantages de Hack en matière de sécurité des types et de refactoring augmentent à mesure qu’il est utilisé dans une base de code. Comprenant qu’il serait difficile pour certains codes d’être complètement transitionnés vers Hack tout de suite, il était important pour nous que Hack soit développé de telle sorte qu’il puisse coexister directement avec d’autres fichiers PHP au fur et à mesure de son introduction incrémentale.

Le reste du processus de conversion, comme l’ajout d’annotations de type et l’utilisation de nouvelles fonctionnalités du langage, peut être fait de manière appropriée pour la base de code. Par exemple, une annotation de type peut être ajoutée pour une fonction mais laissée de côté pour une autre fonction, même dans le même fichier. Si un paramètre de fonction ou un membre de classe n’a pas d’annotation de type explicite, le vérificateur de type considère que son type est dynamique, et il ne vérifie pas le type de cette valeur.

Au sein de Facebook, nous avons constaté que nos ingénieurs appréciaient suffisamment Hack pour qu’ils commencent à convertir volontairement la majorité de leur propre code. Avec des millions de lignes de code dans notre arbre, nous voulions aussi une certaine forme d’automatisation, donc nous avons construit et utilisons un certain nombre d’outils de modification de code pour aider le processus (que nous publions dans le cadre de Hack).

Ne vous inquiétez pas, votre PHP est sûr !

HVM est toujours un runtime PHP, et nous avons l’intention de le garder ainsi. En fait, nous travaillons dur pour atteindre la parité avec PHP-5. L’une des principales priorités de HHVM est d’exécuter un code source PHP-5 non modifié, à la fois pour la communauté et parce que nous nous appuyons sur des bibliothèques PHP tierces en interne.

HVM est maintenant un moteur d’exécution qui prend en charge *à la fois* PHP et Hack, de sorte que vous pouvez commencer à profiter des nouvelles fonctionnalités de Hack de manière incrémentielle.

Amusez-vous avec Hack !

Nous sommes ravis d’ouvrir le code source à la fois de Hack et des outils que vous pouvez utiliser pour convertir automatiquement votre base de code. Ce n’est que la première étape, et nous nous engageons à continuer à faire évoluer ce logiciel pour rendre le développement encore plus facile à la fois pour nos propres ingénieurs et pour la communauté au sens large. La valeur de Hack n’est *pas* limitée aux grands projets : avec des informations sur les types, de bons messages d’erreur et un retour rapide, les petites bases de code peuvent également récolter les avantages de Hack.

Le mois prochain, nous présenterons également le langage lors de la journée des développeurs Hack sur le campus de Facebook à Menlo Park, et nous espérons vous y voir en personne ou en ligne.

Nous aimerions avoir vos commentaires sur notre travail jusqu’à présent, et nous vous invitons tous à participer à la communauté HHVM et Hack.

Reconnaissances

De nombreuses personnes ont contribué au développement de Hack.

L’équipe centrale de Hack est composée de Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar et Joshua Van Dyke Watzman.

Un remerciement spécial va à nos premiers adoptants de la communauté pour fournir des commentaires précieux pour améliorer le langage : James Miller, Simon Welsh, Nils Adermann, Fabien Potencier, et Alexander Mols.

Hack est écrit principalement en OCaml. Nous tenons à remercier l’équipe Gallium (INRIA) pour le développement du langage OCaml, et l’équipe Ocsigen (CNRS – Université Paris Diderot – INRIA) pour le développement de la partie js_of_ocaml d’Ocsigen.

Et, bien sûr, merci à tous ceux qui ont contribué à faire de Hack le langage qu’il est aujourd’hui. La liste est trop exhaustive pour un billet de blog, mais vous savez qui vous êtes.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.