domingo, 16 de diciembre de 2012

Codificar y ejecutar, ¿serie o paralelo?

Se viene algo grande en PSeInt. Por suerte 2012 ha sido un año de muchos muchos avances, y parece que 2013 también va empezar con novedades. Había advertido que no iba a hacer nada nuevo por un buen tiempo, pero me topé con un concepto demasiado bueno como para andar esperando tanto. Navegando sin rumbo llegué a un post de un tal Bret Victor, un tipo que parece tener ideas más que interesantes sobre cómo deberían ser los entornos de programación (entre otras cosas) y cómo la gente debería aprender a programar. Gracias a ese artículo dí con este video. Si miran el video (que dura más de una hora, pero yo solo vi los primeros 20 minutos cuando me decidí a empezar todos estos cambios), van a entender de qué se trata. No estoy 100% de acuerdo en todo lo que propone, pero sí en su gran mayoría, al menos pensando a nivel didáctico que es lo que me ocupa en PSeInt. Y hay momentos de la charla realmente fantásticos, de esos que le abren a uno la cabeza y lo hacen ver las herramientas que tenía desde un punto de vista completamente nuevo.

El tipo plantea un entorno de desarrollo donde los pasos para programar no son primero codificar, luego ejecutar para ver que sale, y repetir; sino que propone codificar y ver qué sale en simultáneo. Es decir, a medida que el programador va codificando el programa, este se va ejecutando, y si a mitad de una ejecución cambia algo del código fuente, la ventana de ejecución refleja inmediatamente esos cambios. El video muestra otras cosas interesantes, pero esa idea tan simple y complicada a la vez fue la que más me impactó. Aquí les presento mi video, de solo 2 minutos, con algunas de estas ideas llevadas a PSeInt:


Digo que la idea es simple por el concepto: no tener que volver a ejecutar si a mitad correr el algoritmo vemos que había un error o faltaba algo, sino modificar el código y observar directamente los resultados sobre la misma ejecución, y así también (y esto es lo más importante) poder experimentar los cambios en tiempo real, para entender mejor qué significan y cómo afectan el resultado. Esto se conoce como Live Coding. Pero es complicado, por un lado porque técnicamente no es fácil de hacer. Creo que por ahora solo tiene sentido intentarlo en lenguajes interpretados, donde tenemos un control más flexible de la ejecución, como para hacer cambios a mitad proceso; o en lenguajes muy simples y limitados como para plantear alguna alternativa más trucha sin que se note. Firefox y su opción para inspeccionar una página y modificar su estructura html o su hoja de estilos en tiempo real es un buen ejemplo de algo parecido. En un lenguaje compilado, hacer un cambio sobre la marcha es casi imposible. Visual Studio tiene su famoso Edit and Continue que hace una magia parecida: permite pausar la depuración, modificar algo, recompilar, y continuar con la versión modificada. Toco de oido porque no lo uso, pero creo que el proceso sigue estando medio separado por eso de pausar, recompilar y seguir (lo cual puede llevar un buen tiempo) y los cambios no se reflejan completamente por que lo que ya se ejecutó no se vuelve atrás, pero igual es una funcionalidad altamente envidiable. Los que conozcan algo de arquitectura de computadoras, sistemas operativos y qué hace un compilador a bajo nivel, intenten imaginar la cantidad de desafíos técnicos que supone implementar algo como eso.

Pero volviendo a los lenguajes interpretados, igual puede haber problemas. Mostrar los cambios de un programa que produce un resultado estático (un dibujo en el ejemplo de Bret Victor, un resultado de un cálculo podría ser en PSeInt) es fácil; pero mostrar los cambios en algo que se mueve, no. Las entradas, por ejemplo, pueden cambiarlo todo y dejar de tener sentido luego de una modificación; o pueden depender del tiempo y entonces reproducirlas con los cambios plantea nuevos inconvenientes. En el video de Bret Victor hay un ejemplo muy logrado de un minijuego de plataforma, y hay otro con una prueba de escritorio a la par del código, pero no veo forma de generalizar eso. Creo que estas ideas se aplican bien a problemas de juguete y lenguajes limitados, pero todavía no en la vida real. Además, creo que hay muchas razones de peso por las cuales un buen programador todavía debe ser capaz de convertirse en la máquina además de en el programa, parafraseando la famosa cita de Alan Perlis que Bret Victor intenta refutar. Aún así, PSeInt es un lenguaje de juguete y bien limitado, y entonces muchas de sus ideas resultan aplicables.

Lo primero que hice, entonces, fue hacer mi propia terminal donde correr los algoritmos. Esta terminal tiene la particularidad de registrar todas las entradas por teclado que hace el usuario. Luego, puede utilizar ese registro para reproducir toda la ejecución hasta cierto punto. Y esto es lo que hace cuando algo cambia en el pseudocódigo, vuelve a ejecutar todo desde cero, ingresando automáticamente otra vez los mismos datos, y mostrando así como queda la ejecución hasta el punto en que estaba luego del cambio. Es posible gracias a que el tipo de entrada en PSeInt es muy simple y acotado. Si esta re-ejecución es suficientemente rápida, se ve como la magia que Bret Victor mostraba en el video. Dado que PSeInt se usa para aprender (léase ejercicios de libro, no problemas serios y súper complejos), es altamente probable que lo sea.  Además, con esto de guardar la entrada y poder reproducir de cero la ejecución, puedo reproducirla parcialmente, y luego cambiar las entradas. Esto quiere decir, a ojos del usuario, que puedo volver en el tiempo el algoritmo hasta un punto pasado, y seguir desde allí como si fuera la primera vez. Las posibilidades son enormes y por ahora apenas estoy comenzando a experimentar. Esto todavía está muy lejos de lo que plantea el autor orinal, pero también está algo lejos de lo que tenía hasta ahora, así que supongo que estos cambios significarán un salto cualitativo interesante si se saben aprovechar.

De todas formas, pensando en el futuro cercano, a menos que encuentre (o se me ocurra a mí, eso sería todavía mejor) otra idea genial (y que pueda implementar), después de esto sí deberían mermar las grandes novedades. La primer mitad de 2013 debería traer solo mejoras a las funcionalides ya implementadas. Tengo grandes deudas, como hacer que el módulo para exportar a C++ exporte también subprocesos, hacer que el nuevo editor de diagramas de flujo exporte las imágenes para desprenderme del viejo definitivamente (y tal vez hasta permitir imprimirlas), arreglar la compilación en Mac para que esta versión esté a la par de las de Windows y GNU/Linux, mejorar la ayuda, actualizar la descripción del pseudocódigo y los ejemplos del sitio web, tal vez incorporar algún tutorial, etc. El tiempo dirá, pero por lo pronto estén atentos que en cualquier momento se publica esta gran actualización.

1 comentario:

  1. wow esta entrada esta muy interesante
    saludos sigue trabajando en eso :)

    ResponderEliminar