Go: Lo que acertamos, lo que nos equivocamos

Una retrospectiva del co-creador de Go, Rob Pike, ha reavivado el debate sobre lo que el lenguaje acertó y se equivocó en su diseño y evolución. Quienes comentan atribuyen en general a Go herramientas rápidas, una sólida biblioteca estándar, primitivas de concurrencia sencillas y un núcleo deliberadamente pequeño y estable que lo convirtió en una opción popular para servidores e infraestructura. Las críticas se centran en el débil soporte de FFI y de computación científica, el largo retraso y las limitaciones actuales de los generics, los problemas generalizados con nil y el manejo de errores, los errores en empaquetado y versionado, y un estilo de liderazgo que algunos ven como desdeñoso de las necesidades de la comunidad, especialmente en torno al manejo de errores, los REPL y las API de tiempo/crypto.

El nicho previsto de Go y en lo que se convirtió

  • Diseñado en Google como un reemplazo más simple y rápido de C++ para servidores y “software de sistemas” (en un sentido amplio: servidores, redes, infraestructura), no para kernels ni drivers.
  • Varios comentaristas dicen que Go terminó siendo más bien un lenguaje de “servidor / backend de internet” y de CLI que un lenguaje de sistemas de bajo nivel.
  • Algunos sostienen que desplazó con éxito a mucho C++ y parte de Python en trabajos de servidores/infraestructura; otros dicen que compite más con Java/C# que con C/C++/Rust.

Computación científica, FFI y HPC

  • Se informa que el equipo inicial de Go descartó los casos de uso de computación científica/HPC, los REPL y la integración con lenguajes de scripting; esto se ve como una oportunidad perdida.
  • cgo y la sobrecarga de llamadas C del compilador gc son ampliamente criticados; Go se considera con una historia de FFI débil, especialmente para computación científica donde la interoperabilidad con C/Fortran es crucial.
  • Contraargumento: la mayor parte del trabajo científico es scripting en Python/R/Julia; Go, como lenguaje de sistemas, no encaja de forma natural de todos modos.

Concurrencia y goroutines

  • Las goroutines se describen como “hilos verdes” en espacio de usuario o programación M:N con fibras con pila sobre hilos del SO; útiles para servidores de alta concurrencia.
  • Algunos creen que Go vendió demasiado las goroutines como algo novedoso; otros las ven como un modelo práctico y exitoso, a pesar de ser similar a sistemas de hilos verdes más antiguos.
  • Este modelo de concurrencia complica C FFI e influye en el diseño del runtime (por ejemplo, no generar código en tiempo de ejecución).

Manejo de errores, panics y nil

  • Los errores como valores más los panics es una de las áreas más debatidas:
    • Críticos: patrones verbosos y repetitivos if err != nil, fácil tragar errores accidentalmente, dos mecanismos paralelos (errores vs panics) que no encajan limpiamente, y un manejo doloroso de nil (incluyendo trampas de nil en interfaces vs tipos concretos).
    • Defensores: los errores explícitos son simples y predecibles, fomentan el manejo y evitan el flujo de control oculto.
  • Los punteros nil y la falta de seguridad contra null se citan como grandes errores de diseño; algunas herramientas (por ejemplo, linters, analizadores de nil) intentan mitigar esto.

Generics y sistema de tipos

  • El largo retraso antes de añadir generics se debate intensamente:
    • A favor: esperar evitó diseños defectuosos que habrían sido difíciles de corregir después.
    • En contra: lanzar sin generics repitió viejos errores (por ejemplo, Java antes de generics), deformó APIs y forzó soluciones alternativas (interface{} por todas partes).
  • Los generics actuales se consideran útiles pero incompletos (por ejemplo, faltan generics a nivel de método), y están محدودados por la semántica existente de las interfaces.

Módulos, empaquetado y herramientas

  • El comportamiento temprano de GOPATH/go get y la importación por URL son criticados por ingenuos y demasiado adaptados al monorepo de Google; los gestores de paquetes de la comunidad crecieron en ese vacío.
  • Los módulos oficiales y MVS suelen ser elogiados como una gran mejora, aunque SIV (v2+) , los repositorios privados y la configuración de SSH/git siguen siendo puntos problemáticos.
  • gofmt, las herramientas unificadas (go build/test/fmt), los binarios estáticos y la compilación relativamente rápida son vistos ampliamente como fortalezas importantes.

Proceso comunitario y evolución

  • Algunos ven al liderazgo de Go como demasiado desdeñoso/lento ante problemas como generics, tiempo monótono, actualizaciones de crypto, REPLs y el uso de context.
  • Otros elogian la disposición a decir “no”, mantener el lenguaje pequeño y priorizar la estabilidad y las herramientas sobre la acumulación rápida de características.