1 puntos por GN⁺ 2026-03-12 | 1 comentarios | Compartir por WhatsApp
  • La lógica de resolución de tipos (type resolution) del compilador de Zig fue rediseñada por completo, simplificando su estructura interna y aportando mejoras visibles para los usuarios
  • El nuevo diseño procesa de forma perezosa (lazy) el análisis de campos de tipos, por lo que evita inspeccionar innecesariamente la estructura detallada de tipos no inicializados
  • Los mensajes de error de bucles de dependencias (dependency loop) mejoraron de forma concreta, permitiendo identificar con claridad la causa del ciclo
  • Se resolvieron el problema de análisis excesivo en la compilación incremental (incremental compilation) y numerosos bugs, lo que mejora notablemente la velocidad de compilación
  • Este cambio incluye decenas de correcciones de bugs y pequeñas mejoras del lenguaje, reforzando en general el rendimiento y la experiencia de desarrollo del compilador de Zig

Rediseño de la lógica de resolución de tipos

  • Se fusionó un PR de unas 30 mil líneas, reescribiendo la lógica de resolución de tipos del compilador de Zig con una estructura más lógica e intuitiva
    • En este proceso se ordenó la estructura interna del compilador, con mejoras directas también para los usuarios
  • El compilador ahora evalúa de forma diferida el análisis de campos de tipos, evitando explorar innecesariamente la estructura detallada de tipos no inicializados
    • En el código de ejemplo, si una estructura que incluye un campo @compileError se usa solo como namespace, antes se producía un error de compilación, pero ahora compila correctamente
    • Esto evita dependencias de código innecesarias al usar tipos con forma de namespace como std.Io.Writer

Mejora de los mensajes de error de bucles de dependencias

  • Antes, los mensajes de error de bucles de dependencias eran ambiguos, pero ahora muestran con claridad la causa y la ubicación del ciclo
    • En el código de ejemplo, cuando las estructuras Foo y Bar se refieren entre sí, el mensaje de error señala de forma específica dónde depende cada tipo del otro
    • El mensaje incluye la longitud del ciclo, la ubicación de la declaración de cada campo y la ubicación de la consulta de alineación
  • Incluso en ciclos complejos, se proporciona suficiente información para identificar fácilmente la causa del problema

Mejora de rendimiento en la compilación incremental

  • Con este cambio se corrigieron numerosos bugs de la compilación incremental
    • En particular, se resolvió el problema de análisis excesivo (over-analysis), optimizando la recompilación para que solo se vuelvan a compilar las partes modificadas
    • Como resultado, en muchos casos la velocidad de compilación mejora notablemente
  • Los desarrolladores pueden activar la compilación incremental en Zig 0.15.1 o superior para probar esta experiencia de desarrollo mejorada

Otras mejoras

  • Este PR incluye decenas de correcciones de bugs, pequeños cambios del lenguaje y mejoras de rendimiento del compilador
    • La mayoría corresponde a detalles o casos especiales
  • El historial completo de cambios puede consultarse en PR #31403 en Codeberg
  • Se recomienda reportar issues si se descubren nuevos bugs

Importancia del cambio

  • La simplificación de la lógica de resolución de tipos y la optimización de la compilación incremental refuerzan la estabilidad y eficiencia del compilador de Zig
  • Los desarrolladores reciben retroalimentación más rápida y clara, y pueden esperar mayor productividad incluso en bases de código grandes

1 comentarios

 
GN⁺ 2026-03-12
Comentarios en Hacker News
  • Soy el autor de este devlog
    Entiendo la preocupación por las rupturas de compatibilidad causadas por cambios en el lenguaje, pero quiero aclarar que este cambio del compilador no es de una magnitud que vaya a causar un impacto grande
    Por ejemplo, al compilar ZLS con la nueva rama, solo hizo falta cambiar .{} por .empty. Esto se debe a la eliminación del valor por defecto de std.ArrayList, que ya llevaba 1 año en estado deprecated
    También en el caso del proyecto Awebo, solo hubo tres cosas que corregir en todo el árbol de dependencias: el cambio a .empty, agregar comptime y agregar orelse @alignOf(T)
    La mayoría de estos cambios son lo bastante simples como para que la mayoría de los desarrolladores de Zig los resuelvan casi en automático
    El punto central de este PR no es tanto la ruptura, sino la corrección de bugs y la mejora de la compilación incremental

    • Yo fui una de las personas que dejó comentarios que parecían críticos con el cambio
      Creo que la calidad y la planificación del PR son muy altas, y nunca tuve la intención de menospreciar el esfuerzo del autor
      Más bien, me quedó la lección de que en adelante debería comentar más y dejar opiniones con más cuidado
    • No participo directamente en Zig, pero al ver el comentario agregado en lib/std/multi_array_list.zig me surgió una duda
      No entiendo por qué usar @alignOf(T) en la definición de MultiArrayList(T) genera una dependencia circular
      Incluso si T fuera MultiArrayList en sí, ¿no sería un tipo monomórfico completamente distinto? Siento que se me está escapando algo
      Código relacionado: enlace
  • Tengo curiosidad por la experiencia de quienes usan Zig en producción
    Como el lenguaje cambia seguido, me interesa saber cómo manejan los ciclos de actualización o de reescritura, y si pasa que los paquetes de dependencias se quedan atrás respecto a la versión del lenguaje
    Sé que Bun aprovecha bien Zig, pero me gustaría escuchar otros casos

    • Mantengo una base de código de un compilador en Zig de unas 250 mil LoC (roc-lang/roc)
      Durante los últimos 1 o 2 años, los cambios del lenguaje y de la librería estándar han avanzado sin mayores problemas
      Antes las actualizaciones eran molestas, pero ahora se sienten más como una pequeña incomodidad
      Si me preguntaran por la experiencia de usar Zig, este aspecto es tan estable que casi ni lo mencionaría
    • He trabajado en dos bases de código Zig de producción: tigerbeetle y sig
      Este tipo de proyectos grandes actualizan tomando como base releases etiquetados, y normalmente completan la migración en unos días o unas semanas
      Además casi no tienen dependencias, así que el costo de actualizar no es alto
    • Zig 0.15 es bastante estable
      Eso sí, a veces un error tipográfico menor provoca un crash del compilador con SIGBUS, lo que vuelve difícil depurar
      .zig-cache llegó a crecer hasta 173GB, y eso también causó problemas en un VPS ARM
      Subir lightpanda de 0.14 a 0.15 fue bastante tranquilo. No creo que 0.16 traiga grandes problemas tampoco
      Pero como desarrollador de librerías, sí cuesta seguir el ritmo de cambios rápidos de 0.16
      Por ahora solo lo estoy manejando experimentalmente en la rama “dev”
    • Estoy corriendo en producción unas 20 mil LoC de Zig 0.16 en modo DebugSafe
      Reescribí un módulo de Node.js/TypeScript en Zig, y quedó 2 veces más rápido y con 70% menos uso de memoria
      El soporte de Zig para serialización de sqlite/JSON fue una gran ventaja
      El lado negativo es que, por la ausencia de sintaxis para closures o vtables, cuesta más separar capas en el código
      Con Arcs y un allocator tipo bumper logré mantener la seguridad de memoria, y pienso seguir operándolo en modo DebugSafe
      Al pasar a ReleaseFast sí hubo una mejora de 25% en velocidad, pero no lo suficiente como para compensar la pérdida de seguridad
    • Creo que la promesa eterna de compatibilidad hacia atrás de C++ en realidad fue un error que frenó la evolución del lenguaje
      Aunque haya que modificar código, a largo plazo sigue siendo el enfoque correcto
  • Me ha impresionado lo que ha logrado el equipo de Zig
    Uso seguido la terminal ghostty hecha en Zig, y es muy estable
    Aun así, personalmente prefiero Rust
    Rust adopta un modelo de “mundo cerrado”, mientras que Zig adopta uno de “mundo abierto”
    En Rust hay que implementar explícitamente un trait, pero en Zig basta con que la forma (shape) del tipo coincida para que funcione
    Gracias a eso, Zig permite una metaprogramación muy potente, pero también tiene la desventaja de que la inferencia de tipos es menos clara y eso complica el autocompletado, la documentación y el soporte de LSP

    • Me gustaría ver un ejemplo concreto
      Por cómo lo explicas, suena parecido a las interfaces de Go, pero tengo entendido que Zig no tiene un concepto equivalente directo
  • Me pareció interesante la transición de kernel32 a Ntdll
    Es una idea que también podría aplicarse a la API de espacio de usuario de Linux
    En particular, el manejo de errores en la frontera kernel-usuario es similar
    Eso sí, en Linux libc y el kernel están muy entrelazados, así que usar errno es imprescindible
    Me da curiosidad por qué en Windows terminó apareciendo un patrón de este tipo

    • Los patrones de errno o GetLastError() son herencia de la era anterior a los hilos
      Antes, con scheduling cooperativo, una variable global era segura, pero cuando llegaron los multicore y los hilos eso se volvió peligroso
      Por eso apareció thread local como alternativa
  • En vez de usar tipos como si fueran namespaces, me pregunto si no sería mejor agregar namespaces explícitos al lenguaje

    • Zig apunta al minimalismo del lenguaje
      La idea es agregar una funcionalidad solo cuando sea algo que optimice varias partes a la vez
    • En realidad no es un rodeo, sino una elegancia del diseño
      En Zig, @import convierte un archivo en una struct, y los namespaces simplemente se representan como struct anidadas
      Es decir, un namespace no es más que otro import
      (Todavía no me entra bien el café, así que no garantizo precisión total)
  • Hay algo que a menudo se pasa por alto en las discusiones sobre cambios de lenguaje: el impacto en el ecosistema
    Si el lenguaje rompe compatibilidad seguido, no solo las apps sino también librerías, herramientas y tutoriales tienen que seguirle el paso constantemente
    Al final, eso inclina el ecosistema hacia proyectos mantenidos activamente, más que hacia librerías de “se hizo una vez y se dejó ahí”
    Ese puede ser un tradeoff razonable en la etapa inicial de diseño de un lenguaje, pero a largo plazo sí afecta el crecimiento del ecosistema
    Otros lenguajes nuevos están invirtiendo mucho esfuerzo en minimizar esta fatiga por cambios
    También será interesante ver qué resultados trae el enfoque de Zig

    • Un ejemplo sería el ecosistema de addons de Blender
      Blender rompe la API con frecuencia, pero la mayoría de los cambios son menores
      Aun así, alguien tiene que arreglarlos, y si el mantenimiento se abandona, al usuario le toca parchearlo por su cuenta
      Los addons de pago tienen más probabilidad de seguir mantenidos, pero ni así hay garantía
    • Aun así yo creo que Zig lo vale
      Las librerías sin mantenimiento de todos modos son código malo
      En vez de criticar a Zig, mejor dejen de promocionar otros lenguajes (como C3)
  • Lo que se menciona en el PR de Zig sobre que “Chromium, boringssl, Firefox y Rust llaman a SystemFunction036 de advapi32.dll” no es cierto
    Ellos ya usan ProcessPrng, que en Windows 10 en adelante no falla
    La base está en este whitepaper de Microsoft
    Está diseñado para que las solicitudes de RNG nunca fallen, y si algo falla, el proceso mismo termina
    Es decir, no devuelve códigos de error para garantizar números aleatorios de alta calidad

    • (Esto es una respuesta a otro devlog de la misma página)
  • La semántica del lenguaje de Zig parece simple en la superficie, pero sus interacciones son sutiles
    Eso me hace pensar que con el tiempo podrían aparecer casos límite complejos, como pasó con las reglas de templates en C++

  • Un PR de 30 mil líneas es un logro tremendo
    Pero me sorprendió que se cambie la semántica del lenguaje, porque es algo muy importante
    Entiendo que Zig todavía no llega a 1.0 y que por eso los cambios van rápido, pero expresiones tan casuales como “cambiamos la semántica en esta rama” me descolocaron un poco
    Me pregunto si este tipo de cambios grandes forma parte de la cultura propia de Zig o si simplemente yo ya me estoy quedando atrás
    La expresión “modern Zig” también me dio risa por la velocidad a la que cambia el lenguaje

    • Que el tono sea casual no significa que haya una actitud ligera
      El devlog no es un texto de marketing, sino más bien un registro para gente del círculo interno, y Zig todavía no es 1.0
      El PR sí incluye suficiente contexto y fundamentos
      Si elegiste Zig, en cierto nivel ya aceptaste el riesgo de cambios en el lenguaje
      De hecho, pulirlo bien ahora trae más beneficios a largo plazo
      (Piensa en herencias imposibles de corregir, como la precedencia de operadores bit a bit en C)
    • mlugg es colaborador principal de Zig y miembro de la Zig Foundation
      Este cambio busca resolver dependencias circulares y ordenar el sistema de tipos
      Las propuestas relacionadas están publicadas en #3257 y #15909
      Con esto, la resolución de tipos de Zig queda organizada como un DAG (grafo acíclico dirigido), lo que mejora mucho la estabilidad del compilador
      Zig se maneja bajo un modelo BDFN (Benevolent Dictator For Now), y la decisión final la tiene Andrew Kelley
      Pero el equipo funciona como una organización sin fines de lucro y pone por delante la confianza de los usuarios y la calidad del lenguaje
      En lo personal, trabajar junto a Matthew es un gran honor
    • Quizá esta actitud sea el resultado de tomar como advertencia la historia caótica del lenguaje C
      Era impecable en lo formal, pero en la práctica terminó siendo un lenguaje caótico