5 puntos por GN⁺ 2025-08-23 | Aún no hay comentarios. | Compartir por WhatsApp
  • Varias decisiones de diseño del lenguaje Go se tomaron de forma innecesaria o ignorando experiencia previa ya existente
  • El problema de gestión del alcance de las variables de error dificulta la legibilidad del código y la búsqueda de bugs
  • En varios aspectos, como la dualidad de nil, el uso de memoria y la portabilidad del código, aparecen diseños poco intuitivos y alejados de la realidad
  • Las limitaciones de la sentencia defer y la forma en que la biblioteca estándar maneja situaciones excepcionales dificultan garantizar la seguridad ante excepciones
  • Los problemas acumulados, como la gestión de memoria y el deficiente manejo de UTF-8, están afectando negativamente a largo plazo la calidad de los codebases en Go

Crítica de largo plazo al lenguaje Go

La falta de intuición en el alcance de las variables de error

  • La sintaxis de Go amplía innecesariamente el alcance de la variable de error (err), aumentando la posibilidad de errores
    • En el código de ejemplo, la variable err permanece viva durante toda la función y se reutiliza, lo que perjudica la legibilidad y mantenibilidad del código
    • Incluso desarrolladores con experiencia sufren malentendidos y pérdida de tiempo al rastrear bugs debido a estos problemas de alcance
    • La sintaxis no permite limitar correctamente esas variables a un ámbito más local

Dos formas de nil

  • En Go existe la confusión de que nil se comporta de manera distinta en tipos interface y tipos puntero
    • Como en el ejemplo de abajo, aunque se asigne nil a s (puntero) e i (interface), s==i se evalúa de manera distinta, mostrando un comportamiento inconsistente
    • Este es el tipo de problema que normalmente se quiere evitar al manejar null, y deja ver una falta de reflexión suficiente en el diseño

Límites de la portabilidad del código

  • El uso de comentarios para compilación condicional es claramente ineficiente en términos de mantenibilidad y portabilidad
    • Si alguna vez se ha creado software verdaderamente portable, es fácil ver que este enfoque es engorroso y propenso a errores
    • Se ignoró la experiencia acumulada históricamente en portabilidad de código y casos prácticos reales
    • Para más detalles, puede consultarse Go programs are not portable

La falta de claridad sobre la propiedad en append

  • La relación de propiedad entre la función append y los slices no es clara, lo que dificulta predecir el comportamiento del código
    • A través del ejemplo, resulta difícil saber de antemano qué efecto real tendrá sobre el original hacer append al slice dentro de la función foo
    • Aumentan así las “quirks” del lenguaje que hay que memorizar, lo que termina provocando errores

Diseño insuficiente de la sentencia defer

  • No ofrece un soporte claro para liberar recursos como sí lo hace el principio RAII (Resource Acquisition Is Initialization)
    • A diferencia de las sentencias estructuradas de gestión de recursos en Java y Python, en Go no queda claro qué recursos deben liberarse con defer
    • Como muestra el ejemplo con archivos, incluso hay que lidiar manualmente con problemas de double-close, y no queda claro cuál es el orden ni la forma correctos de liberar recursos

Manejo de excepciones en la biblioteca estándar

  • Go es una estructura que no soporta excepciones explícitas (exception), pero aun así siguen ocurriendo situaciones excepcionales como panic
    • En algunos casos, panic ni siquiera termina por completo el programa, sino que queda absorbido
    • Existen patrones en la biblioteca estándar (fmt.Print, servidores HTTP, etc.) que ignoran excepciones, por lo que no es posible garantizar una verdadera seguridad ante excepciones
    • Al final, escribir código seguro ante excepciones sigue siendo indispensable, pero no se pueden usar excepciones directamente

UTF-8 y las cadenas

  • Aunque se meta cualquier dato binario arbitrario en el tipo string, Go funciona sin hacer una validación especial
    • Puede ocurrir que nombres de archivo creados antes de la codificación UTF-8 simplemente se omitan silenciosamente
    • En tareas como respaldos esto puede causar pérdida de datos importantes, y refleja un enfoque simplista que no toma en cuenta situaciones reales de trabajo

Límites de la gestión de memoria

  • Es difícil tener control directo sobre el uso de RAM, y la confiabilidad del GC (garbage collection) también tiene límites
    • El uso de memoria de Go crece y eso termina convirtiéndose a largo plazo en problemas de costo y rendimiento
    • En entornos con múltiples instancias y contenedores, realmente surgen problemas de costos y escalabilidad

Conclusión: había caminos mejores

  • Aunque ya existían diseños de lenguajes que habían demostrado su eficacia, Go los ignoró en muchos aspectos
    • A diferencia de los problemas de los primeros borradores de Java, cuando Go fue lanzado ya existían enfoques mejores

Material de referencia

Aún no hay comentarios.

Aún no hay comentarios.