9 años de python

9 años han pasado desde que escribí mi primer Hola, mundo! en python, por allá del 2011 (aunque la fecha es imprecisa, podría haber sido bastante antes pero no recuerdo). Desde entonces he escrito de todo, desde pequeños scripts bobos para organizar cosas en mi computadora hasta ambiciosos sistemas en red que constan de varios servicios. Python reemplazó a PHP como mi lenguaje por defecto para cualquier tipo de proyectos por ahí del 2013 (debo admitir que tomó más de lo esperado) y desde entonces no me ha dejado de acompañar en mi camino como desarrollador y arquitecto.

Aquí recuento algunos momentos importantes en esta apasionada historia de amor y código.

El inicio

Para cuando conocí python tenía un buen dominio de PHP, Java y Javascript. Fue en una conferencia de un tal David Sanders (quien a estas alturas ya migró a Julia) que dió en la Facultad de Matemáticas donde yo estudiaba. La emoción no se hizo esperar. Un lenguaje ciertamente más limpio y consistente que PHP, con aplicaciones en cómputo científico y simulación, pero también con vertientes en web y hasta escritorio, y con un intérprete interactivo y montones de paquetes para hacer monerías.

Rápido lo aprendí, siempre por mi cuenta, aprovechando de su facilidad y fascinado de que el lenguaje simplemente se comportaba como yo esperaba. Aprendía algunas cosas y el resto eran casi una consecuencia. Tal fue mi emoción que construí un hola mundo que condensaba las maravillas que había descubierto.

El cambio

Pese a toda esa fascinación tardé en reemplazar PHP pues con éste último ya sabía bien cómo hacer lo que mejor hacía por el momento: levantar sitios web. Python era ciertamente más placentero de trabajar pero fundamentalmente diferente respecto a cómo levantar un proyecto web, el framework más popular Django se oponía a ser aprendido con facilidad debido a sus tremendas funcionalidades y los sitios de hosting no la ponían fácil.

Pese a todo esto lo seguí utilizando más y más, incluso llegué a dar cursos en mi facultad, usarlo para mis clases y hasta lo introduje durante un semestre completo en la clase de programación como una alternativa a C.

Eventualmente Django cedió, apareció cherrypy y flask en las posibilidades y me animé a comenzar algunos proyectos. Puedo decir con satisfacción que este cambio moldeó completamente cómo concebiría el software a futuro, fuertemente influenciado por el buen diseño que siempre me pareció tener el lenguaje, la limpieza, la consistencia etc.

Retrospectiva

Hoy, nueve años después, me permito asomarme a este lenguaje con una mirada más crítica pero aún llena de agradecimiento.

La facilidad de uso y la naturalidad de su API ahora se me presentan con sus respectivas sombras, en las que se ocultan costos en memoria o tiempo de ejecución fáciles de adquirir, difíciles de pagar. Todas esas capas de abstracción también me retrasaron un conocimiento más profundo acerca del funcionamiento interno del lenguaje y su interacción con la computadora que ahora me es invaluable.

La limpieza que viene con la falta de llaves la veo ahora también desde la perspectiva didáctica, pues he estado enseñando el lenguaje desde que lo aprendí y puedo ver que aunque menos símbolos quitan ruido, un par de símbolos más (las llaves) no necesariamente lo aumentan: la verdad a veces hasta dan más claridad del ámbito de una variable o el principio y fin de las cosas.

La consistencia creo que fue de las primeras cosas que cuestioné, por ejemplo dentro de la biblioteca estándar el módulo unittest siempre me pareció que iba en contra de toda la filosofía de diseño de python, por suerte tenemos pytest para olvidar ese pequeño desliz.

Respecto al manejo de errores generé un buen entendimiento y disciplina que me serviría en cualquier lenguaje que use excepciones, sin embargo que el mismo lenguaje no me ayudara a encontrar errores sin manejar o que tuviera la falsa noción de que podía recuperarme de cualquier excepción nunca me convenció del todo. Después me enamoraría del manejo de errores de Rust.

Quizá influenciado por el conocimiento que ahora tengo de Rust encuentro en python un lenguaje poco adecuado en situaciones donde la certeza de correctitud es un factor relevante, como en entornos de alta disponibilidad y confiabilidad. Si bien los tipos son fuertes la falta de una verificación estática de los mismos no permite atrapar errores a tiempo. Es cierto que algunos linters (mención honorífica a flake8) permiten detectar algunos errores a tiempo y mypy es una promesa importante en este sentido, pero lograr un buen soporte de tipos aún en el caso de que mypy funcionara a la perfección es sueño guajiro, un poco como en javascript.

Y respecto a este último punto no me malentiendan, cualquier lenguaje con nulos y casting alegre entre tipos peca de los mismos problemas: C# lo hace mal, Java lo hace peor.

Agradecimiento

Con esto no se debe pensar que estoy dejando el lenguaje para siempre. Todo lo contrario, me sigue pareciendo una elección de primera clase para las tareas en las que brilla: prototipado rápido, desempeño razonable, estable. Definitivamente un buen punto de entrada. Al menos tres proyectos interesantes míos se escribieron primero en python para después ser portados a Rust.

Adicional a la bien conocida sintaxis limpia y estable de python hay un par de cosas que siempre me gustaron y que a la fecha uso como referencia de algo bien hecho:

Biblioteca estándar. ¿Qué podría uno necesitar que no venga ya por defecto con el lenguaje? Cuando dicen Baterías incluídas hablan bien en serio.

Documentación. A mi humilde parecer python como lenguaje tiene una de las mejores documentaciones disponibles: fácil de navegar, completa, llena de ejemplos y notas de uso. Aprendí python por mi cuenta leyendo casi exclusivamente contenido de https://docs.python.org, tanto del tutorial, la biblioteca estándar y los How to.

Dependencias y paquetes. Aunque hacer paquetes para python no es tan sencillo como en otros lenguajes se me ocurre pensar que fue eso lo que creó ecosistemas de pocas dependencias: el más grande de mis proyectos debe tener una veintena, hoy comienza un proyecto javascript y arrancas de cajón con un millar y medio. Y de las pocas cosas que no existen en la biblioteca estándar o que no son lo suficientemente buenas existe allá afuera algún paquete que no solo lo hace bien, sino excelente (e.g. requests, numpy, ...).

Tracebacks. La forma en que python muestra los errores me pareció en su momento bastante limpia. En general no es tan difícil saber qué es lo que está pasando y rastrear las llamadas hasta encontrar el punto en tu código que es la probable causa del problema.