Internals de la compilación incremental de Zig
El nuevo sistema de compilación incremental de Zig busca que las recompilaciones tras pequeños cambios de código sean casi instantáneas al almacenar en caché IR de grano fino y parchear los binarios en su lugar, aunque por ahora se orienta a compilaciones de depuración y a backends autoalojados sin optimizaciones pesadas. Los comentaristas comparan este modelo con Rust, C, Java y Fil-C, y debaten cómo el diseño del lenguaje, las canalizaciones de compilación y funciones como genéricos, macros y borrow checking afectan tanto a los tiempos de compilación como a las garantías de seguridad de memoria. El hilo también aborda estrategias alternativas como el enlazado dinámico de muchas bibliotecas compartidas pequeñas, y cuánto complejidad o coste en tiempo de ejecución es aceptable en la búsqueda de iteración más rápida y código de bajo nivel más seguro.
Compilación incremental en Zig
- El modo incremental actual solo funciona con los backends autoalojados de Zig (no LLVM), principalmente x86_64, y por ahora es en la práctica “solo depuración”.
- Plan a futuro: añadir pases de optimización a los backends autoalojados y eventualmente soportar algún tipo de compilación de release, pero las optimizaciones entre funciones (p. ej., inlining) están fundamentalmente en tensión con este modelo y seguirán siendo limitadas.
- El diseño del lenguaje Zig se ha ido ajustando con el tiempo (a veces de forma controvertida) específicamente para hacer tratable la compilación incremental de grano fino y el análisis semántico.
Compilación de C y dependencia de LLVM
- La recompilación incremental solo se aplica a fuentes Zig en proyectos mixtos Zig/C; C se compila mediante LLVM y no se almacena en caché con la misma granularidad.
- Existe un compilador de C basado en Zig (Aro/arocc) usado para
translate-c(traducción de cabeceras), pero aún no como backend general de C. Los planes de compilación de C a más largo plazo todavía se están diseñando.
Por qué un único binario grande y enlazado incremental
- Algunos cuestionaron por qué Zig parchea un binario grande de depuración en lugar de componer muchas bibliotecas compartidas pequeñas.
- Respuestas:
- Zig usa un modelo de una sola unidad de compilación; los archivos separados son una cuestión organizativa, no fronteras de compilación, así que la mayor parte del trabajo incremental (análisis sintáctico, análisis semántico) seguiría siendo necesaria de todos modos.
- Dividir en muchas bibliotecas compartidas trasladaría en gran medida el trabajo del enlazador estático al cargador dinámico, perjudicando el inicio en tiempo de ejecución; experimentos medidos con cientos o miles de bibliotecas compartidas muestran una sobrecarga notable.
- Se reconoce que el enlazado incremental es complejo, pero se considera el mejor compromiso; las preocupaciones por corrupción se abordarían mediante separación de cachés, detección de corrupción y cancelación segura.
Rust, otros compiladores y tiempos de compilación
- Varias comparaciones con Rust:
- Rust ya tiene compilación incremental, pero sufre por la complejidad del lenguaje (macros, proc macros, resolución de nombres, genéricos monomorfizados) y el modelo tradicional de “compilar bibliotecas y luego enlazar”.
- Hay trabajo en curso en Rust para mejorar el comportamiento incremental (p. ej., consultas más granulares, “relink don’t rebuild”), pero rearquitectarlo es difícil.
- Algunos sostienen que muchos lenguajes siguen desperdiciando trabajo al compilar bibliotecas enteras incluso cuando solo se usa una pequeña parte; el modelo guiado por demanda de Zig se ve como más limpio.
Seguridad de memoria frente a compensaciones del lenguaje (Rust, Zig, Java, Fil-C)
- Un bando considera que “seguridad de memoria por defecto, con salidas de escape explícitas” (estilo Rust/Java) es la base; otro argumenta que lo importante es el subconjunto seguro útil y la compensación total (complejidad, rendimiento, velocidad de iteración).
- Zig se ve como una mejora sobre C (en particular herramientas de seguridad espacial), pero sigue siendo “inseguro por defecto”; algunos consideran esto aceptable dadas sus metas y ventajas de tooling, otros ven la falta de seguridad de memoria completa como un factor decisivo.
- El debate ampliado compara Rust, Zig, Java, C, ATS y Fil-C:
- Desacuerdos sobre qué debería significar “lenguaje seguro en memoria”, si la posición de Rust es el “mínimo indispensable” y cuánto valor aportan los límites explícitos entre seguro/inseguro.
- Fil-C se discute como una variante experimental de C que usa capacidades y un runtime para impedir muchas clases de explotación. Sus defensores destacan garantías más fuertes; sus críticos señalan sobrecarga en tiempo de ejecución, dependencia de trampas en lugar de pruebas en tiempo de compilación, limitaciones de plataforma e implementación inmadura.
- Varios participantes subrayan que distintos proyectos y equipos elegirán racionalmente puntos diferentes en el espectro seguridad–complejidad–rendimiento.
Hello World y ergonomía
- El “hello world” oficial de Zig es visto por algunos como verboso en comparación con ejemplos al estilo C.
- Defensas:
- Es “más correcto”: manejadores de E/S explícitos, manejo explícito de errores e integración con el modelo de E/S de Zig.
- Existen variantes más simples (p. ej.,
std.debug.printa stderr) para demos rápidas; el ejemplo verboso expone deliberadamente preocupaciones del mundo real en lugar de ocultarlas.