Hack: un nuevo lenguaje de programación para HHVM – Facebook Engineering

¿Tienes prisa? Prueba Hack ahora: http://hacklang.org/

Hoy lanzamos Hack, un lenguaje de programación que hemos desarrollado para HHVM y que interopera perfectamente con PHP. Hack concilia el rápido ciclo de desarrollo de PHP con la disciplina proporcionada por la tipificación estática, al tiempo que añade muchas características que se encuentran comúnmente en otros lenguajes de programación modernos.

Hemos desplegado Hack en Facebook y ha sido un gran éxito. Durante el último año, hemos migrado casi toda nuestra base de código PHP a Hack, gracias tanto a la adopción orgánica como a una serie de herramientas de refactorización de cosecha propia.

También estamos orgullosos de lanzar una versión de código abierto de Hack al público en http://hacklang.org/ como parte de nuestra plataforma de tiempo de ejecución HHVM, que ahora soportará tanto Hack como PHP.

Motivación

Todos los programadores de PHP están familiarizados con las tareas del día a día que pueden ser difíciles o engorrosas. El código anterior es un gran ejemplo de un error común en el que se podría llamar inesperadamente a un método sobre un objeto nulo, causando un error que no se detectaría hasta el tiempo de ejecución. Otro ejemplo es el de una API compleja, en la que los desarrolladores pueden tener una sólida comprensión de su semántica, pero aún así pierden tiempo buscando nombres de métodos mundanos en la documentación.

A escala de Facebook -con miles de ingenieros enviando nuevo código dos veces al día- ralentizaciones como éstas son aún más problemáticas. Antes de Hack, teníamos un lenguaje simple con un bucle de retroalimentación rápida – pero ¿cómo podríamos mitigar los tipos de problemas descritos anteriormente? ¿Podría coexistir la detección temprana de errores con la iteración rápida, preservando al mismo tiempo nuestra inversión en PHP? ¿Podría la mejora del análisis de código y la introspección ayudar a los desarrolladores a ser más productivos con herramientas como el autocompletado?

Tradicionalmente, los lenguajes dinámicamente tipados permiten un desarrollo rápido pero sacrifican la capacidad de detectar errores tempranamente y de introspeccionar el código rápidamente, particularmente en bases de código más grandes. Por el contrario, los lenguajes tipados estáticamente proporcionan una mayor red de seguridad, pero a menudo a costa de una rápida iteración. Creíamos que tenía que haber un punto dulce.

Así nació Hack. Creemos que ofrece lo mejor de los lenguajes de tipado dinámico y de tipado estático, y que será valioso para proyectos de todos los tamaños.

El lenguaje Hack

Hack tiene profundas raíces en PHP. De hecho, la mayoría de los archivos PHP ya son archivos Hack válidos. Hemos tomado la decisión consciente de no dar soporte a un puñado de funciones y características obsoletas que eran incompatibles con el tipado estático (por ejemplo, las «variables variables» y la función extract()). También hemos añadido muchas características nuevas que creemos que ayudarán a los desarrolladores a ser más productivos.

Nuestra principal adición es el tipado estático. Hemos desarrollado un sistema para anotar las firmas de las funciones y los miembros de las clases con información de tipo; nuestro algoritmo de comprobación de tipos (el «comprobador de tipos») infiere el resto. La comprobación de tipos es incremental, de modo que incluso dentro de un mismo archivo parte del código puede convertirse a Hack mientras que el resto sigue estando tipado dinámicamente. Técnicamente hablando, Hack es un lenguaje «gradualmente tipado*»*: el código tipado dinámicamente interopera sin problemas con el código tipado estáticamente.

Dentro del sistema de tipos de Hack, hemos introducido varias características como los genéricos, los tipos anulables, el aliasing de tipos y las restricciones en los parámetros de tipos. Estas nuevas características del lenguaje son discretas, por lo que el código que escriba con Hack se verá y sentirá como el lenguaje dinámico al que los programadores de PHP están acostumbrados.

Sin embargo, Hack añade características adicionales más allá de la comprobación de tipos estáticos, incluyendo Colecciones, expresiones lambda, y la aplicación en tiempo de ejecución de los tipos de retorno y de los tipos de parámetros.

Las Colecciones proporcionan una alternativa limpia y segura a los arrays de PHP. Las hemos diseñado específicamente para que funcionen bien con la tipificación estática y los genéricos. La API de Colecciones ofrece muchas funciones clásicas de orden superior como map() y filter() para facilitar los estilos de programación funcional.

Las expresiones lambda ofrecen una sintaxis concisa para crear cierres. Mientras que PHP tiene cierres, requiere que el programador nombre explícitamente las variables que necesita usar de los ámbitos que lo rodean. Con las expresiones lambda de Hack, inferimos automáticamente estos usos, ahorrando trabajo innecesario. Las expresiones lambda hacen que sea más conveniente aprovechar al máximo la API de Collections.

La aplicación en tiempo de ejecución de los tipos de retorno y de los tipos de parámetros (incluyendo los tipos escalares como int y string) proporciona seguridad más allá de lo que puede comprobarse estáticamente mientras se añaden gradualmente anotaciones de tipo a un código base. La aplicación en tiempo de ejecución ayuda a los programadores a detectar y diagnosticar ciertos tipos de problemas más fácilmente, y ayuda al JIT de HHVM a producir un código más eficiente al hacer que sea seguro confiar en las anotaciones de tipo con fines de optimización.

Comprobación de tipos instantánea

Durante el desarrollo, un programador de PHP suele ir y venir rápidamente entre el código fuente y el navegador. Los ingenieros pueden iterar tan rápido como necesiten, probando y ajustando una experiencia hasta que sea perfecta.

Tradicionalmente, un comprobador de tipos interrumpiría este bucle de retroalimentación ya que lleva tiempo analizar el código fuente. No queríamos ralentizar el flujo de trabajo de PHP, así que ideamos un nuevo enfoque para conciliar la retroalimentación instantánea con la seguridad de tipos.

Nuestra solución fue diseñar el comprobador de tipos como un servidor local que vigila el sistema de archivos. El servidor mantiene toda la información sobre el código fuente en memoria y se actualiza automáticamente cuando un archivo cambia en el disco. Este enfoque ha dado sus frutos: el comprobador de tipos suele ejecutarse en menos de 200 milisegundos y rara vez tarda más de un segundo, lo que facilita su integración en el flujo de trabajo de desarrollo sin introducir un retraso notable.

Migración de código

Los beneficios de la seguridad de tipos y la refactorización de Hack crecen cuanto más se utiliza dentro de una base de código. Entendiendo que sería difícil para algún código ser transitado completamente a Hack de inmediato, fue importante para nosotros que Hack sea desarrollado de tal manera que pueda coexistir directamente con otros archivos PHP a medida que se va introduciendo de manera incremental.

El resto del proceso de conversión, como la adición de anotaciones de tipo y el uso de nuevas características del lenguaje, se puede hacer como sea apropiado para la base de código. Por ejemplo, se puede añadir una anotación de tipo para una función pero dejarla fuera de otra función, incluso en el mismo archivo. Si un parámetro de una función o un miembro de una clase no tiene una anotación de tipo explícita, el comprobador de tipos considera que su tipo es dinámico y no comprueba el tipo de ese valor.

Dentro de Facebook, descubrimos que nuestros ingenieros apreciaban Hack lo suficiente como para empezar a convertir la mayoría de su propio código de forma voluntaria. Con millones de líneas de código en nuestro árbol, también queríamos alguna forma de automatización, por lo que construimos y utilizamos una serie de herramientas de modificación de código para ayudar en el proceso (que estamos liberando como parte de Hack).

No te preocupes, tu PHP está a salvo!

HHVM sigue siendo un tiempo de ejecución de PHP, y tenemos la intención de mantenerlo así. De hecho, estamos trabajando duro para alcanzar la paridad con PHP-5. Una de las principales prioridades de HHVM es ejecutar el código fuente de PHP-5 sin modificaciones, tanto para la comunidad como porque confiamos en las bibliotecas de PHP de terceros internamente.

HHVM es ahora un tiempo de ejecución que soporta *ambos* PHP y Hack, por lo que puede comenzar a tomar ventaja de las nuevas características de Hack de forma incremental.

¡Diviértase con Hack!

Estamos encantados de abrir el código abierto tanto de Hack como de las herramientas que puede utilizar para convertir automáticamente su código base. Este es sólo el primer paso, y estamos dedicados a seguir evolucionando este software para hacer el desarrollo aún más fácil para nuestros propios ingenieros y la comunidad en general. El valor de Hack *no* se limita a los grandes proyectos: con información de tipo, buenos mensajes de error, y una rápida retroalimentación, las pequeñas bases de código pueden cosechar los beneficios de Hack también.

El próximo mes, también presentaremos el lenguaje en el Día del Desarrollador Hack en el campus de Facebook en Menlo Park, y esperamos verte allí en persona o en línea.

Nos encantaría tener sus comentarios sobre nuestro trabajo hasta el momento, y les damos la bienvenida a todos a participar en la comunidad HHVM y Hack.

Agradecimientos

Hay muchas personas que han contribuido al desarrollo de Hack.

El equipo principal de Hack está formado por Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar y Joshua Van Dyke Watzman.

Un agradecimiento especial a los primeros usuarios de la comunidad por sus valiosos comentarios para mejorar el lenguaje: James Miller, Simon Welsh, Nils Adermann, Fabien Potencier y Alexander Mols.

Hack está escrito principalmente en OCaml. Nos gustaría dar las gracias al equipo Gallium (INRIA) por el desarrollo del lenguaje OCaml, y al equipo Ocsigen (CNRS – Universidad de París Diderot – INRIA) por el desarrollo de la parte js_of_ocaml de Ocsigen.

Y, por supuesto, gracias a todos los demás que han ayudado a hacer de Hack el lenguaje que es hoy. La lista es demasiado exhaustiva para una entrada de blog, pero ya sabéis quiénes sois.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.