Incorporar un sistema de compilación dentro del compilador de OCaml

Fuentes: Retrofitting a build system into a compiler

El verano de Lucas Ma, bajo la tutela de Anil Madhavapeddy, giró en torno a una idea ambiciosa: usar el sistema de efectos del lenguaje OCaml, introducido en la versión 5.0, para convertir el propio compilador en una biblioteca bajo demanda, un "servicio de compilación" de larga vida. El reto no es la idea en sí, sino implementarla sobre una base de código de tres décadas diseñada para compilaciones aisladas de un solo paso.

El primer paso fue generalizar Load_path, el mecanismo interno que el compilador usa para localizar ficheros de tipos (extensión .cmi). Los efectos permiten invertir el control: el programa que invoca al compilador puede interceptar estas búsquedas y, lo más importante, mentir al compilador sobre qué ficheros existen realmente. Esto desbloquea la posibilidad de ignorar el grafo de dependencias tradicional, ya que cuando el compilador solicita un .cmi ausente, el sistema puede generarlo en el momento compilando el fichero correspondiente.

El paso siguiente consistió en reentrar en el propio proceso del compilador en lugar de lanzar uno nuevo, suspendiendo y reanudando la compilación mediante continuaciones. El obstáculo principal fue el abundante estado mutable global del comprobador de tipos, no reentrante por motivos de rendimiento. La solución vino de Merlin: su mecanismo Local_store permite capturar instantáneas del estado global. Lucas Ma amplió este mecanismo para usar Domain Local Storage, lo que facilita la paralelización con dominios múltiples, cada uno compilando un fichero .ml diferente en paralelo.

El resultado es un prototipo muy sencillo, escrito apenas en unas pocas líneas, capaz de reconstruir el compilador de bytecode de OCaml partiendo únicamente de la lista de ficheros .ml, sin orden de dependencias explícito y retirando en la práctica la herramienta ocamldep. Desde una perspectiva de cadena de herramientas, se trata de un sistema de compilación simple, portable y paralelo construido sobre el propio compilador, lo que allana el camino hacia un bootstrap trivial de OCaml.