Tiempo de lectura: 8 minutos
Imagen: Mario Hinojosa Freire

Aprendemos a programar con Python, JavaScript o C, según qué estudiemos… Pero ¿y si hubiese una opción mejor?

Los recién llegados al mundo de la programación tienen sus primeras tomas de contacto con lenguajes distintos, dependiendo de dónde se formen. Los ingenieros suelen venir de C o C++. Los alumnos de formaciones profesionales suelen trabajar con Java o .NET, y los grados relacionados con videojuegos tienden más a formarse en C#. Por último, los estudiantes de bootcamps o cursos de desarrollo web, suelen aprender Javascript o Python.

Todos estos lenguajes tienen sus virtudes y defectos, y no hay una forma correcta de aprender a programar. Sin embargo, hay una opción con muchas ventajas que prácticamente nadie aprovecha para enseñar las bases de la programación.

La abstracción y la dificultad

Para explicar las virtudes de Go y porqué es tan buena opción para aprender, hay que entender el concepto de abstracción. Resumidamente, la abstracción es una filosofía de diseño que consiste en ocultar, simplificar o gestionar de forma automática ciertos detalles con el fin de facilitar el uso.

Un ejemplo claro de abstracción son los garbage collectors. Los garbage collectors son automatizaciones de la gestión de memoria, que liberan al programador de la responsabilidad de hacerlo manualmente. En C, el lenguaje menos abstracto de la lista, es necesario aprovisionar de forma manual la memoria dinámica con funciones como malloc() o calloc().

En el más abstracto, Python, todo ese trabajo lo hace de forma automática el garbage collector, que se encarga de identificar memoria aprovisionada por el programa pero que ya no se referencia (llamada basura o garbage) y liberarla. Esta tarea recae en las manos del programador en C, que ha de liberar la memoria con la función free().

En contraste con la memoria estática, que se reserva para variables a la hora de compilar el programa, la memoria dinámica es la que se asigna una vez el programa ya está corriendo, posterior a la compilación y durante la ejecución.

Ejemplo en C

int *ptr = malloc(15000); // Crea una variable (de tipo puntero) llamada ptr y le asigna un tamaño de 15000 bytes  
  
free(ptr); // El programador debe liberar a mano la memoria cuando ya no la necesita para evitar fallos de rendimiento y/o seguridad

«Equivalente» en python

ptr = "A" * 1875 ## Crea una variable llamada ptr de 15000 bytes, que será liberada de forma automática cuando esta ya no esté referenciada

Pros y contras

Empezar por lenguajes muy abstractos, como Python o Javascript tiene sus ventajas. No requieren comprender conceptos complejos como punteros o gestión de memoria, su sintaxis suele ser más sencilla y su curva de aprendizaje mucho menos pronunciada. Esto puede servir como una ruta de aprendizaje viable para algunos propósitos, pero deja lagunas de conceptos muy importantes que merece la pena aprender bien desde el principio.

Lenguajes menos abstractos, como C o C++, obligar a atravesar ese reto inicial de comprender conceptos complejos del low-level, dando una base muy sólida a un aprendiz que alcance la fluidez en C. Sin embargo, ambos son lenguajes difíciles, con curvas de aprendizaje pronunciadas, comunidades menos amigables con novatos, menos recursos online…

Cada caso individual es un mundo en sí mismo y no hay una decisión correcta a la hora de escoger una vía, todo depende de las circunstancias y el objetivo. Sin embargo, de forma generalista, Golang podría ser uno de los mejores lenguajes para iniciarse en la programación por varias razones.

¿Qué es Golang?

Go es un proyecto open-source desarrollado por un equipo de Google. «Go nace de la frustración con los lenguajes y entornos existentes…». Los creadores del lenguaje identificaron varios problemas con el estado del desarrollo en torno al año 2007, y se pusieron manos a la obra.

«Cuando Go fue diseñado, Java y C++ eran los lenguajes más usados para desarrollar servidores, al menos en Google. Sentíamos que estos lenguajes requerían demasiado trabajo administrativo y repetición. Algunos programadores reaccionaron pivotando a lenguajes más dinámicos y fluidos como Python, sacrificando eficiencia y seguridad de tipos. Nosotros sentíamos que sería posible aunar la eficiencia, seguridad y fluidez en un solo lenguaje.»

Go fundamente su filosofía de diseño en la simplicidad y la sencillez, con una sintaxis limpia y ligera. Algunas decisiones son más polémicas que otras (como el famoso := para declarar variables), pero no se puede negar que un programa de Go idiomático se lee rápido y fácil.

Con los años, Go ha recibido 26 actualizaciones mayores desde su primera versión, arreglando, optimizando y puliendo el lenguaje. Aunque no es tan popular como otros lenguajes, su uso está masivamente generalizado en desarrollo de servidores, aplicaciones CLI, desarrollo web, servicios de nube y redes, entre otros.

Las razones por las que Go podría ser una buena opción

Go es equilibrado

¿En qué lado cae Go? ¿Abstracto o low-level? El lenguaje logra un equilibrio entre ambos que lo convierte en una opción ideal para el aprendizaje. Para alcanzar un nivel avanzado, es necesario interiorizar y comprender conceptos complejos, como punteros, gestión de memoria (no manual, pero sí para optimizar la carga que asume el garbage collector), buffers, I/O, métodos…

La diferencia con C es que aunque es necesario (y deseable), aprender todo esto para ser un buen programador de Go, son retos del camino que no pronuncian demasiado la curva de aprendizaje, y no es necesario aprenderlos al principio para escribir un programa funcional.

Go es fácil

Además, la sintaxis relacionada a estos conceptos complejos es sencilla e intuitiva, a diferencia de otros lenguajes, en los que la sintaxis es un dificultad adicional en lugar de un alivio.

Go es un lenguaje rápidp de aprender, no se tarda mucho en ser en funcional, y la sintaxis es sencilla, fácil de asimilar y usar para alguien que se inicia desde cero. Para cualquier programador que venga de casi cualquier otro lenguaje, será como poco familiar. Los tipos son básicos y aprender las diferencias entre ellos y empezar a manipularlos también.

Go tiene muchos recursos

Para aprender todo esto, Go está muy bien documentado. A nivel oficial tiene muchos recursos de buenísima calidad en la web oficial, como A Tour of Go, Go by Example y la documentación oficial. También tiene una comunidad muy activa, produciendo artículos, cursos, libros, tutoriales y respuestas en foros de altísima calidad.

Por si fuera poco, hay decenas de charlas de los co-creadores en distintas conferencias sobre temas variados, como la razón de algunas decisiones sobre el lenguaje o su funcionamiento interno. Los artículos del blog son también muy buenos, con contenido similar y temas de actualidad.

Go es versátil

Go es versátil por naturaleza. Gracias a su simpleza y algunas decisiones críticas de diseño como la concurrencia integrada, el lenguaje tiene una amplia gama de casos de uso. A esto se suma la comunidad. Desde que Go se hizo open-source, la adopción no ha parado de crecer. En el proceso, los programadores han aportado miles de paquetes muy útiles y variados.

Go es usado por desarrolladores de malware, programadores web y programadores de aplicaciones CLI, entre muchos otros. Puede encontrarse en servidores, aplicaciones de pentesting, fuzzers, UIs… Es utilizado por muchos productos y compañías, como Ollama, Kubernetes, Docker, CloudFlare, Meta, Microsoft, Google… Y potencia infraestructura a lo largo y ancho del mundo, en todos los sectores.

La versatilidad que ser fluido en Go le da a un programador es incomparable a otros lenguajes. Lo cual es también una oportunidad fantástica para aprender, ya que pueden hacerse programas para comprender de forma práctica conceptos clave del desarrollo como I/O, networking, seguridad, interfaces de usuario, concurrencia/paralelismo, servidores web…

Go tiene unas normas claras (y te obliga a entender cosas importantes)

Hay una serie de normas muy claramente definidas por los propios creadores del lenguaje. No son normas para escribir un programa funcional, si no para escribir un programa óptimo. Esto sirve de gran ayuda y genera un estándar claro sobre todo el código, ayudando a cumplir un punto de la filosofía de diseño: que el código sirva de documentación en sí mismo.

En esa sección de la documentación hay una variedad amplia para escribir Go idiomático y exprimir al máximo posible el lenguaje. Además, para utilizar Go en todo su potencial, uno se ve obligado a comprender los punteros para poder trabajar bien con slices, y también a comprender conceptos importantes del software moderno como la concurrencia.

Go es concurrente de forma nativa

La concurrencia es una estrategia de diseño similar al parelelismo, pero más inteligente. El parelelismo consiste en ejecutar varias tareas de forma simultánea e independiente, con un determinado fin pero sin comunicación entre dichas tareas. Debido a que la ejecución es independiente, es necesario duplicar un recurso si se desea procesar en paralelo, y podrían darse interferencias entre un resultado y otro.

Por otro lado, la concurrencia no consiste solamente en ejecutar en paralelo, si no en ejecutar en sincronía. La idea es es tener múltiples procesos trabajando simultáneamente, pero colaborando. Los procesos pueden colaborar esperando a una tarea de otro proceso concurrente o compartiendo información entre sí para no modificar el mismo dato.

Imagen: Mario Hinojosa Freire

En Go la concurrencia se consigue con goroutines, que se pueden definir como hilos muy baratos en cómputo (hay programas en producción que corren millones de goroutines simultáneamente).

Esto es complejo de comprender, y más complejo de implementar, pero hacer software concurrente significa hacer software escalable, resiliente y eficiente. Hay una charla de Rob Pike, uno de los creadores, hablando en profundidad de este tema, aquí hay dos slides de la presentación que pueden ayudar a entender un poco mejor el concepto.

Una tarea de 3 partes: Almacenar, transportar, destruir.
La misma tarea planteada con un diseño concurrente, cada gopher realiza una tarea de forma sincronizada con los demás: Preparar la carga, transportarla a una segunda pila, dejarla y volver a por más carga. En la segunda fase se repiten los procesos, solo que en vez de amontonar en una segunda pila se destruye.

En un diseño paralelo, esto sería tener 4 pilas, 4 gophers y cuatro incineradoras, necesitando multiplicar por 4 la tarea. El diseño concurrente difiere en que los componentes que resuelven la tarea se comunican y sincronizan.

Go y el manejo de errores

Aunque esto podría plantearse como un problema, podría considerarse una ventaja para el aprendizaje. Go obliga a los programadores a gestionar de forma explícita y evidente los errores. Esto puede ser una buena manera de desarrollar el hábito de incluir estructuras de control de errores a la hora de migrar a otro lenguaje.

Go hace buena sinergia con LLMs

Por todas las razones anteriores, sobre todo la buena documentación y sintaxis sencilla, los modelos de IA producen código de Go de buena calidad. Tanto para un vibe-coder como para un programador al uso que utiliza LLMs como apoyo a menudo se pueden apreciar resultados mejores que otros lenguajes.

Go es divertido

Para este último me he reservado el punto más subjetivo. Go es muy divertido de aprender, y divertido de escribir. El proceso de aprendizaje es satisfactorio, el lenguaje es bonito y da gusto escribirlo, además, al ser versátil, permite hacer programar con finalidades variadas en función de lo que más motive a cada uno.

Recomiendo mucho a cualquiera que se inicie en la programación buscar un problema que requiera una solución, o un proceso que podría automatizarse u optimizarse. Entonces, renunciar a la IA durante un par de horas y enfrentarse a la documentación, probar, fallar, corregir. ¿Te atascas? Pide ayuda a un modelo, pero no pidas soluciones. Poco a poco los conceptos irán encajando, y podrás hacer cosas cada vez más difíciles.

En definitiva

No hay un camino claro para aprender, cada uno tiene sus circunstancias, contexto y capacidades, y cualquier cosa que sirva está bien para cada uno. Si te encanta el hardware, C será más útil, si te gusta el data science, probablemente sea mejor Julia, y si quieres ser diseñador web seguramente le saques más partido a Javascript. Pero si lo que quieres es aprender a programar en general, creo que Go es una opción a plantear a la hora de empezar a aprender.