7 puntos por GN⁺ 2026-02-18 | 1 comentarios | Compartir por WhatsApp
  • En Go 1.26 se introduce un comando go fix completamente reescrito que puede mejorar el código automáticamente aprovechando las funciones más recientes del lenguaje y de las bibliotecas
  • Esta herramienta detecta patrones de código mediante decenas de analizadores (analyzers) y aplica distintos modernizadores (modernizers) como minmax, rangeint y stringscut para convertir código repetitivo o anticuado a formas más modernas
  • Para dar soporte a la nueva función new(expr), se agregó el analizador newexpr, que puede simplificar automáticamente funciones auxiliares como newInt
  • go fix genera efectos de sinergia al ejecutarse varias veces: distintos analizadores pueden proponer mejoras consecutivas, e incluye fusión automática de conflictos y eliminación de imports innecesarios
  • El equipo de Go planea ampliar esto en el futuro mediante un paradigma de análisis de autoservicio (Self-service), para que los desarrolladores puedan definir y distribuir modernizadores para sus propias API

Resumen del comando go fix

  • En Go 1.26, go fix fue reimplementado por completo para ofrecer conversión automática de bases de código al estilo más moderno de Go
    • El comando go fix ./... modifica todos los paquetes bajo el directorio actual
    • La opción -diff permite previsualizar los cambios
  • La lista de analizadores registrados puede consultarse con go tool fix help, e incluye varias reglas de transformación como any, forvar, mapsloop y minmax
  • Para ejecutar solo un analizador específico se usa una bandera como -any; para excluirlo se indica -any=false
  • Considerando las diferencias de código por plataforma, puede ejecutarse varias veces para distintas combinaciones de GOOS y GOARCH

Modernizers — herramientas de modernización de código

  • Desde Go 1.18, la introducción de genéricos amplió las posibilidades de simplificar código
    • Ejemplo: usar maps.Keys para recopilar claves de un map, o strings.Cut para dividir cadenas
  • Para resolver el problema de que las herramientas de generación de código basadas en LLM mantienen patrones antiguos, se destaca la necesidad de actualizar el código open source reflejando los modismos más recientes de Go
  • Los modernizadores incluidos en go fix y gopls mejoran la legibilidad del código y también su valor de aprendizaje
  • Ejemplos de modernizadores:
    • minmax: reemplaza sentencias if por funciones min/max
    • rangeint: convierte bucles for de 3 cláusulas a range-over-int
    • stringscut: simplifica código basado en strings.Index usando strings.Cut

La función new(expr) en Go 1.26

  • La función new se amplió para aceptar un argumento de valor, permitiendo inicialización con formas como new("go1.26")
  • El analizador newexpr encuentra funciones auxiliares como newInt, las simplifica a return new(x) y reemplaza los puntos de llamada por new(expr)
  • Solo se aplica cuando se cumple la versión mínima de Go requerida, por ejemplo una directiva go 1.26
  • Puede aplicarse a toda la base de código con el comando $ go fix -newexpr ./...
  • Después de usarlo, las funciones auxiliares innecesarias pueden identificarse con la herramienta deadcode

Sinergia y manejo de conflictos

  • Existe un efecto de sinergia donde una corrección crea oportunidades para otras
    • Ejemplo: después de aplicar minmax, pueden aparecer propuestas de transformación adicionales
    • También es posible una optimización en cadena como stringsbuilderfmt.Fprintf
  • go fix usa un algoritmo de fusión 3-way merge para combinar automáticamente conflictos entre cambios
    • Si hay conflicto sintáctico, omite esa corrección y muestra una advertencia
    • Los conflictos semánticos, como eliminación de variables o imports sin uso, requieren ajuste manual
    • Los imports innecesarios se eliminan automáticamente

Integración con el framework de análisis de Go

  • go vet y go fix se integraron para compartir un framework de análisis común
    • vet se enfoca en detectar errores, mientras que fix se centra en correcciones automáticas seguras
  • Los analizadores pueden ejecutarse desde varios drivers como unitchecker, multichecker, gopls, staticcheck y Tricorder
  • Mediante el sistema de facts, es posible compartir información entre paquetes
    • Ejemplo: inferir que log.Printf es un wrapper de fmt.Printf
  • gopls ofrece diagnóstico en tiempo real y sugerencias de corrección automática

Mejoras en la infraestructura de análisis

  • La expansión del paquete inspector mejora la eficiencia de exploración del AST, y el tipo Cursor permite navegar arriba, abajo, izquierda y derecha
  • El indexado de llamadas de función mediante typeindex mejora la velocidad de análisis hasta 1000 veces
  • Mejoras adicionales:
    • disponibilidad del grafo de dependencias de la biblioteca estándar
    • soporte para consultas de versión de Go por archivo
    • ampliación de primitivas de refactorización para permitir cambios seguros como comentar código
  • Algunos modernizadores quedan excluidos por cambios sutiles de comportamiento (caso append([]string{}, slice...)slices.Clone(slice))
  • A futuro se prevé desarrollar un motor de pattern matching, un arnés de pruebas automatizado y una biblioteca precisa de operadores de corrección

Paradigma Self-service

  • Desde Go 1.26 se anticipa la introducción de un modelo de análisis de autoservicio
    • Los desarrolladores podrán definir y distribuir modernizadores para sus propias API
    • Podrá ejecutarse a nivel de proyecto sin un proceso centralizado de aprobación
  • Como primer paso, se incluye en vista previa una función de inliner guiado por anotaciones (Annotation-driven inliner)
  • Planes a futuro:
    • ejecutar analizadores definidos por el usuario mediante carga dinámica (dentro de go fix o gopls)
    • generalizar checks basados en flujo de control, por ejemplo validar invariantes como “open seguido de close” o “lock seguido de unlock”
  • El objetivo es mejorar la eficiencia de mantenimiento y acelerar la adopción de las funciones más recientes de Go

1 comentarios

 
GN⁺ 2026-02-18
Opiniones de Hacker News
  • A finales de 2024, cuando los asistentes de código con LLM se expandieron rápidamente, fue interesante ver que estas herramientas tendían a reproducir tal cual el estilo de código Go existente de sus datos de entrenamiento
    Incluso si se les indicaba que usaran sintaxis moderna, a veces lo ignoraban o hasta negaban que existiera
    Para que los modelos del futuro reflejen los modismos de Go 1.25 más recientes, todo el código open source tendría que actualizarse a ese estilo

    • En PHP también hubo intentos de limpiar los consejos obsoletos de Stack Overflow, como magic_quotes
      Pero una vez que a un LLM le entra información incorrecta, casi es imposible corregirla
      Es difícil rastrear con qué fundamento llegó el modelo a una conclusión, y solo queda esperar que se corrija en la siguiente versión
    • El código de concurrencia en Go que generan los LLM es especialmente peligroso
      Parece simple y pasa la revisión, pero en realidad le faltan manejo de errores y casos límite
      Si después de revisarlo se vuelve a pasar al LLM, sale un código que parece corregido, pero por dentro aparecen data races o deadlocks
      Es un problema que se repite en casi todos los modelos
    • Yo también me topo seguido con este problema
      Go mantiene muy bien la compatibilidad hacia atrás, así que compila, pero el estilo del código termina siendo muy distinto
      En Python sí ocurren rupturas reales de compatibilidad por cambios en la API
      Aun así, Go es excelente como lenguaje para generación de código gracias a la estabilidad del lenguaje y su librería estándar
    • El uso de LLM al final va a producir código uniforme y mediocre
    • Creo que hay que abandonar por completo la idea de escribir código con LLM
      Como advirtió Rob Pike, esta tecnología es una contaminación del ecosistema de software
      Mucha gente quiere la porquería (slop) de la “comodidad”, pero justamente ahí está el problema
  • Una herramienta que transforme automáticamente el código fuente al estilo más reciente es realmente genial
    El ejemplo clásico es OpenRewrite en Java, pero en otros lenguajes no se me ocurren muchas similares
    Si, como en Go, esta capacidad viene integrada en el lenguaje, eso eleva muchísimo la madurez del lenguaje
    Parece probable que los nuevos lenguajes tomen como referencia este enfoque integrado de Go

    • En C existe Coccinelle, y también se menciona en este artículo de LWN de 2009
      Los IDE de JetBrains pueden refactorizar millones de líneas de código de una sola vez o convertirlas automáticamente a sintaxis nueva
      También tienen funciones como ConvertToPrimaryConstructor
      Y Structural Search and Replace trabaja a nivel de sintaxis del lenguaje, no solo de texto simple
      Los analizadores de Roslyn en .NET también ofrecen sugerencias de corrección de código dentro del IDE
      Enlace al tutorial
    • clippy de Rust recomienda sintaxis moderna y en algunos casos también puede corregir automáticamente
      Gracias a eso, el código ha quedado mucho más limpio
    • hlint de Haskell también existe desde hace mucho tiempo
      Puede cambiar concat y map por concatMap, o simplificar expresiones if innecesarias
    • Me pregunto si alguien ha transformado un codebase de TypeScript de esta forma
      Los servidores LSP se quedan cortos y ni siquiera soportan refactorizaciones básicas como quitar argumentos
      Estoy pensando si sería posible combinando jscodeshift o Claude
  • Gracias a estas herramientas de corrección automática (go fix), Go es de verdad un lenguaje sobresaliente
    Tengo expectativas de que la nueva función rangeint también se refleje automáticamente con go fix
    Aplausos para el equipo de Go

    • Muchas veces quiero usar otros lenguajes, pero las herramientas de build, test y lint de Go son tan buenas que al final termino usándolo
      La velocidad de compilación también es increíblemente rápida
    • Antes buscaba y corregía los bucles for directamente con expresiones regulares, pero ahora esta herramienta lo resuelve de una forma mucho más elegante
  • No se mencionó en el artículo, pero mi función favorita es la directiva //go:fix inline
    Inserta en línea, en el llamador, una función de una sola línea
    Permite que quien escribe la librería haga una migración automática y natural de una función vieja a una nueva
    Incluso si cambia el semver, se puede hacer un upgrade automático con go fix

  • En este podcast de Wes McKinney que vi recientemente,
    decía que Go es ideal para agentes de codificación gracias a su ciclo rápido de compilar y ejecutar, su sistema de tipos fuerte y su seguridad en entornos multihilo
    Después de escucharlo, me volvió a interesar Go

  • El consolidado ecosistema de herramientas y convenciones de Go ayuda mucho al desarrollo basado en agentes
    Con go run main.go puedes levantar enseguida el entorno de desarrollo, y además soporta varios worktrees, configuración centralizada y hasta una base de datos con migraciones aplicadas
    En housecat-inc/cheetah comparten herramientas de este tipo
    Estoy pensando en agregar go fix al ciclo rápido que ya incluye go generate, go build, go test y go vet

    • La velocidad de compilación ultrarrápida también es una gran ventaja para iterar con LLM
  • Aprendiendo Python me di cuenta de que hay demasiadas formas distintas e inconsistentes de hacer lo mismo
    Hasta extrañé que fuera como C, donde hay básicamente una sola manera
    Me pregunto si Go ya llegó a ese punto
    Quiero saber si es un lenguaje en el que puedes seguir las mejores prácticas sin ayuda de un LLM

    • Go es un lenguaje bastante opinado, así que en general hay una sola forma de hacer las cosas
      Me impresiona el esfuerzo por evitar complejidad y mantener la simplicidad
      Se lo recomiendo a cualquiera que esté cansado del caos de Python
  • El concepto de self-service analyzer me parece realmente interesante
    Da la impresión de que los equipos de librerías grandes o infraestructura lo van a aprovechar bastante

  • Con una herramienta así, dan ganas de pensar que hasta un lenguaje sin compatibilidad hacia atrás podría ser viable

  • En el mundo de TypeScript, biome cumple ese papel
    Por ejemplo, recomienda for...of en vez de forEach, y si lo usas junto con ultracite el flujo de trabajo se vuelve mucho más fluido
    En el archivo agents.md dejé escrito “ejecutar biome fix después de modificar”, y gracias a eso la calidad del código se mantiene automáticamente
    La experiencia es mucho más ligera y eficiente que con eslint