Por qué existe Python 3



Una traducción del artículo Why Python 3 exists, por Brett Cannon.

Este mes realicé una conferencia en PuPPy (el grupo de usuarios de Python de Puget Sound) que eventualmente me llevó a explicar por qué nació Python 3 y todo el asunto cadena / secuencia de bytes (string / bytes). Terminé recibiendo un cumplido en la explicación, lo que en cierta forma me sorprendió ya que ingenuamente asumí que, a esta altura, la gente ya sabía por qué Python 3 había sido creado. En retrospectiva, fue un tanto absurdo el asumir que a la mayoría de la gente, nueva o antigua en Python, se les había comentado o bien despertado la curiosidad de explorar y encontrar una explicación. Por lo tanto, este artículo tiene como objetivo simplemente explicar por qué existe Python 3, y específicamente por qué elegimos hacer todo el cambio unicode / str / bytes, incompatible con versiones anteriores, ya que éste es el verdadero problema al portar código a Python 3.

Los datos binarios y de texto en Python 2 son un desastre

Rápido, ¿qué representa semánticamente la siguiente expresión?

'abcd'

Si eres usuario de Python 3 dirías que es la cadena conformada por las letras «a», «b», «c», y «d» en ese orden.

Si eres usuario de Python 2 habrás dicho lo mismo. También habrás dicho que eran los bytes representando 97, 98, 99, y 100. Y está el hecho de que hay dos respuestas correctas en Python 2 por lo que el objeto str representa, lo que llevó a cambiar el lenguaje para que la respuesta de Python 3 fuera la única.

El Zen de Python dice que «Tendría que haber un — y preferiblemente únicamente uno — camino obvio para hacerlo». Tener expresiones en el lenguaje que podían representar tanto datos de texto como binarios era un problema. Si leías algo de la red, por ejemplo, tenías que ser muy cuidadoso en decir que el objeto str que retornabas representaba datos binarios o de texto, porque no había forma de saberlo una vez que el objeto estaba fuera de tu control. O podrías tener un error en tu código cuando tenías la intención de convertir ese objeto str a datos de texto — o algo más íntegramente — pero metiste la pata y accidentalmente olvidaste ese paso. Teniendo al objeto str representando potencialmente dos tipos semánticos diferentes era difícil determinar cuándo este tipo de errores ocurría.

Ahora intentarás argumentar que todos estos inconvenientes eran solucionables en Python 2 si evitabas el uso del tipo str para datos textuales y, en su lugar, te basabas en el tipo unicode para el texto. Si bien esto es estrictamente correcto, la gente no lo hace en la práctica. O bien los programadores se vuelven perezosos y no quieren decodificar a Unicode porque es trabajo extra, o tratan de evitarlo para obtener mejor rendimiento en la velocidad de ejecución. De todas formas es asumir que escribirás tu código lo suficientemente bien como para no arruinarlo, y todos sabemos que somos seres humanos falibles e imperfectos. Si la esperanza de la gente de escribir código sin errores en Python 2 hubiera dado resultado entonces no estaríamos escuchando reiteradamente de casi cada persona que porta su proyecto a Python 3 que encontró errores latentes en su código relacionados con la codificación y decodificación de datos de texto y binarios.

Este punto de evitar errores es un gran problema del que la gente se olvida. La simplificación del lenguaje y la eliminación de la parte implícita de lo que un objeto str podría representar hace el código menos propenso a errores. El Zen de Python indica que «explícito es mejor que implícito» por una razón: la ambigüedad y el conocimiento implícito que no es código fácilmente comunicado es más fácil de corromperse y conlleva a errores. Al forzar a los desarrolladores a separar explícitamente los datos binarios de los datos de texto se obtiene un mejor código que presenta menos chances de tener algún tipo de error o bug.

El resto del mundo ha ido por Unicode (por una buena razón)

A veces la gente se olvida lo antiguo que es Python; Guido empezó a desarrollar Python en Diciembre de 1989 y fue lanzado como código abierto en Febrero de 1991. Esto significa que Python precede al primer volumen del estándar Unicode que apareció en Octubre de 1991. En los años siguientes, los lenguajes creados luego del estándar Unicode decidieron basar su implementación de cadenas en codificaciones que pudieran soportarlo. Esto puso a Python 2 en una posición desafortunada mientras ganaba popularidad en 2004 (cuando comenzaron los planes para Python 3), pero tenía sin duda el soporte más endeble para textos Unicode ya que el uso del tipo unicode era íntegramente opcional y la gente no lo estaba utilizando.

Soportar Unicode y texto de cualquier lenguaje escrito es importante. Python es un lenguaje para el mundo, no únicamente para aquellos idiomas que soportan el alfabeto romano que cubre el código ASCII. Es por esto que Python 3 lo hace «Unicode o nada» cuando se trata de texto; garantiza que todo el código en Python 3 soportará a cualquiera en el mundo independientemente de si el desarrollador que lo escribió lo indicó explícitamente. En Python 2 hay una gran divergencia entre los proyectos que se tomaron el tiempo de soportar unicode correctamente para datos de texto y aquéllos que no lo hicieron; en Python 3 no existe tal división y el soporte para todos los idiomas viene gratis.

Asumimos que Python se iba a volver más popular

En 2004 comenzamos el documento PEP 3100 y por ende el diseño de Python 3 (al margen: el PEP fue nombrado originalmente 3000, pero lo renumeramos a 3100 para que el PEP que tenga el número 3000 fuera en el que explicábamos cómo íbamos a manejar el desarrollo de Python 3). Sabíamos que la popularidad de Python se encontraba en alta y esperábamos que siguiera en esa dirección (lo que agradecidamente sucedió ☺). Pero esto también significaba que si íbamos a reparar cualquier error de diseño y promover la popularidad del lenguaje, debíamos hacerlo en ese mismo momento más que en otro. Asumimos que más código sería escrito en Python 3 antes que en Python 2 por un período de tiempo lo suficientemente largo, considerando que no haríamos Python 3 a la ligera mientras durara más que Python 2 y fuera utilizado más frecuentemente una vez que Python 2.7 fuera empleado únicamente para proyectos preexistentes. Por lo que decidimos soportar el dolor de la transición Python 2/3 y creamos Python 3 bajo esta suposición. Obviamente tomaría décadas poder ver si Python 3 superaría a Python 2 en términos de líneas de código.

Nunca volveremos a hacer este tipo de cambios incompatibles

Como un equipo hemos decidido que un cambio tan grande como el de unicode / str / bytes no volvería a ocurrir tan abruptamente. Cuando comenzamos con Python 3 pensamos y teníamos la esperanza que la comunidad haría lo que hizo Python, es decir, lanzar una última versión soportando Python 2 y luego migrar el desarrollo a Python 3 para incluir nuevas funcionalidades mientras que la versión de Python 2 recibía únicamente actualizaciones de seguridad o corrección de errores. Esto obviamente no sucedió y hemos aprendido nuestra lección. Además no vemos ningún defecto en el diseño fundamental del lenguaje que pueda justificar la necesidad de un cambio de tales características. Por ende no esperen que Python 4 haga algo más drástico que, tal vez, remover módulos obsoletos de la librería estándar.

Conclusión

Entonces ésa es la razón por la que Python 3 es como es. Nos dimos cuenta que había una colección de errores que la gente seguía teniendo debido al uso intensivo del tipo str en Python 2, y los arreglamos en Python 3 separando claramente los datos de texto de los binarios. También ayuda que todo tipo de datos textuales soporten Unicode automáticamente, ya que los proyectos son de repente mucho más capaces de trabajar con múltiples idiomas. E hicimos el cambio cuando lo hicimos porque consideramos que cuanto antes mejor. Estructuramos la transición pensando que la comunidad se nos uniría en dejar Python 2 atrás, pero éste no fue el caso y en lugar de eso terminamos usando por un tiempo más un subconjunto del lenguaje compatible con ambas versiones.



Deja un comentario