jueves, 13 de febrero de 2014

Polimorfismo en psexport

Psexport es uno de los módulos de PSeInt, el que se encarga de traducir un algoritmo en pseudocódigo a lenguajes de programación reales como C, C++, Java, PHP, etc. En realidad hace la mitad del trabajo. Traducir implica primero entender qué es lo que está escrito en un lenguaje, para luego ver cómo escribirlo en el otro. La primer parte la hace el mismísimo intérprete, generando un archivo intermedio "premasticado" para que psexport lea más fácilmente y dedique sus mayores esfuerzos a ver cómo sería mejor escribirlo en ese otro lenguaje. Inicialemente, ese otro lenguaje era solo C++, pero recientemente se añadieron unos cuantos más. La orientación a objetos y particularmente el polimorfismo hicieron que pueda programar todas esas nuevas traducciones con muy poco esfuerzo. Así que en este post les voy a mostrar un ejemplo del tan valioso y no siempre bien ponderado polimorfismo.

viernes, 7 de febrero de 2014

Polimorfismo en C++

El uso del polimorfismo en C++ es uno de los temas que más complicaciones les trae a los estudiantes cuando están haciendo sus primeras armas en C++ y Programación Orientada a Objetos. Aclaro que estoy hablando de clases abstractas y métodos virtuales, porque algunos materiales cuentan la sobrecarga como un tipo de polimorfismo. Tal vez se deba a que para utilizarlo hay que tener claras las ideas de la POO y el diseño de clases por un lado (algo muy difícil si se tiene poca experiencia), y por otro lado los conceptos del manejo de memoria en C++, ya que involucra punteros y conversiones implícitas de tipo. Es decir, ni el diseño ni la sintaxis son triviales. Entonces es lógico que les resulte complejo. El problema es que culpa de esto, le esquivan todo lo posible, y terminan no utilizándolo.

Se puede hacer todo tipo de cosas en C++ sin utilizar polimorfismo, es posible evitarlo, o emularlo. Pero en muchísimos casos, hacerlo de esa manera implica más código, clases más complejas, implementaciones más rebuscadas, más dependencias entre objetos, o el uso de otros trucos tanto o más complicados que el mismo polimorfismo que estaban tratando de evitar. Voy a comentar en este artículo rápidamente de qué se trata, cuales son los mecanismos del compilador que hay por detrás, y qué usos le podemos dar, para que sirva de introducción a otros artículos donde comentaré casos particulares y de interés en PSeInt y en ZinjaI.

viernes, 31 de enero de 2014

Sobre la evolución de C++

Aproveché una parte de las vacaciones para tratar de ponerme al día con el "nuevo" estándar de C++: C++11. Digo "nuevo" porque aunque el estándar (el documento que describe el lenguaje) tiene ya 3 años, recién el año pasado los principales desarrolladores de compiladores publicaron versiones con soporte suficientemente estable y completo para las nuevas características y bibliotecas (gcc 4.8, clang 3.3, visual studio 2013, etc). No vengo a explicar las nuevas características, sino que les voy a contar a modo de recomendación de dónde me informé, y que otras cosas muy interesantes me encontré en el camino; para al final tratar de pensar cómo y cuando nos va a afectar esto.

El que me conozca o siga el blog sabe que el 90% (o más) de lo que programo, lo hago con C++. Se convirtió en mi lenguaje favorito por cuestiones más bien pragmáticas, y por oposición a alternativas (discutiblemente) más simples, modernas, o prolijas, pero en general menos eficientes. Estos motivos no hicieron más que afirmarse y crecer durante estas semanas, gracias a algunas lecturas adicionales que encontré en el camino.

domingo, 29 de diciembre de 2013

Lecciones de un proyecto no proyectado

Hoy se cumplen 10 años desde que PSeInt fue presentado por primera vez en "público". El 29/12/2003 rendí el final de "Programación I", evaluación que incluía mostrar y defender un programa desarrollado por el alumno con lo aprendido en la materia. No tengo ningún registro exacto de cuándo empecé a codificarlo así que tomo esa presentación formal como fecha de nacimiento. Ni se imaginan lo horrible y lleno de bugs que estaba el código, pero como yo no era consiente de ello, se lo vendí a los docentes como si fuera maravilloso, corriendo sin problemas los ejemplos con los que ya lo había probado. Y como en el poco tiempo que dura el examen no se puede ahondar en tantos detalles, los muchos errores escondidos no saltaron a la vista y me fui con una muy buena nota.

Más allá de eso, jamás imaginé que PSeInt seguiría vivo al día de hoy, y mucho menos que iba a cambiar y evolucionar en la forma en que lo hizo. Siempre le vi patas cortas a este proyecto, y eso me privó de explotarlo un poco más, de hacerlo crecer antes, y de utilizarlo para otras cosas, algo que hoy en algún sentido lamento no haber hecho. De eso vengo a contarles en este post. La historia de un proyecto muy querido pero a la vez subvalorado por su desarrollador. Sobre las veces que dejé pasar oportunidades por falta de imaginación, y cómo el tiempo me demostró que siempre se puede hacer algo más. Espero que este post ayude a salvar algún que otro proyecto con potencial de algún lector, que haya quedado escondido en un cajón por su falta de visión a largo plazo.

domingo, 15 de diciembre de 2013

¿Dónde va la gente cuando viene?

Blogger, la plataforma sobre la cual funciona este blog, me ofrece ciertas estadísticas básicas del tráfico del blog. Una de las listas que me ofrece es la de los posts más leídos, diaramente, semanalmente, mensualmente, o en total. Y resulta que el post de este blog más leído de todos los tiempos es uno de los que menos me interesaba. Ni imaginaba que fuera a llamar tanto la atención. Y por otro lado, otros posts que a mí me parecieron mucho más entretenidos o útiles, recibieron relativamente pocas visitas. Les sugiero, si son más o menos seguidores del blog, que traten de recordar cuales posts les llamaron más la atención, o les resultaron más útiles, antes de hacer click en "seguir leyendo" o de pasar al próximo párrafo, para ver si coinciden más conmigo o con las estadísticas.

sábado, 7 de diciembre de 2013

Creación de complementos. Paso 3: empaquetado

Llegamos al últimos de esta serie de posts destinado a mostrar cómo se arman complementos para ZinjaI basados en bibliotecas externas. Vamos a ver a hora cómo utilizar la herramienta que empaqueta los archivos y genera el .zpc que después podemos instalar fácilmente en cualquier ZinjaI. Resumiendo mucho, los pasos que necesarios para llegar hasta aquí fueron:
  1. Obtener los archivos necesarios para compilar un programa cliente de la biblioteca con MinGW. Esto incluye cabeceras, objetos y dlls. Lograr compilar y ejecutar un ejemplo con estos archivos. Más...
  2. Armar una carpeta con lo mínimo necesario y modificar la configuración del proyecto para que busque esa carpeta en un ruta relativa a la instalación de ZinjaI. Más...
  3. Generar el índice de autocompletado, configurarlo en el proyecto, agregar un botón para acceder fácilmente a la referencia, y guardar todo eso como template de proyecto. Más...
Resta juntar todo lo que tenemos, acomodarlo para el generador de complementos, y obtener finalmente el archivo .zcp. Veamos cómo.

lunes, 2 de diciembre de 2013

SFML y sus dependencias

Los cambios en la interfaz binaria de los objetos compilados con MinGW hicieron que deba recompilar algunas bibliotecas externas. Compilar una biblioteca no siempre es fácil en Windows, y encima con SFML me llevé algunas sorpresas interesantes que vengo a comentar aquí.

Las bibliotecas libres suelen tener sus procesos de construcción basados en alguna herramienta libre para tal fin, como pueden ser los scripts de autotools, o la herramienta cmake. Estas herramientas son comunes en GNU/Linux, pero no en Windows (lo común en Windows creo que sería tener un proyecto de Visual Studio). Entonces, como conseguir un entorno apto para estas compilaciones no es tan directo, siempre que podamos conseguir las versiones ya compiladas de las bibliotecas para Windows, mejor (más fácil y más rápido). Es lo que pasó al principio con SFML. Para armar el complemento de sus primeras versiones (1.5 y 1.6), yo no compilé SFML, sino que bajé la versión compilada que se ofrece en su sitio oficial y le agregué lo necesario para utilizarla en ZinjaI (como las plantillas de proyectos ya configurados y los indices de autocompletado).

viernes, 29 de noviembre de 2013

Creación de complementos. Paso 2: extras

Ya tenemos un proyecto que anda, y configurado de forma que solo copiando un par de carpetas de un ZinjaI a otro podemos replicarlo. En esta tercera parte vamos a pulir algunos detallecitos y a generar el bendito índice de autocompletado que hará que ZinjaI nos ayude a utilizar las clases y funciones de la biblioteca mientras escribimos el programa cliente.

Empecemos por generar el índice. Lo vamos a hacer automáticamente a partir de las cabeceras (los .h y .hpp). Esto no siempre es lo mejor, porque a veces tienen definidas cosas demás, que no nos interesan para el autocompletado (como las guardas), o porque a veces no se condicen con la documentación. Digamos por ejemplo que para una clase Ventana la documentación dice que va "#include <Ventana.h>", pero en realidad Ventana.h no tiene la clase sino un montón de #ifs que según el sistema operativo hacen un #include diferente con la versión de la clase para cada sistema operativo. El parseo automático dirá por ejemplo que Ventana está en <Win32/Ventana.h> mientras que lo correcto es poner solo <Ventana.h> o de lo contrario no compilará en otro sistema. Como este hay muchos casos, y por eso los índices de wxWidgets y SFML-1 se generaron parseando los archivos de la referencia HTML y no las cabeceras. Pero este parseo es ad-hoc y requiere mucho trabajo (y programar), así que vamos por la forma fácil y esperemos que no traiga demasiados problemas.

sábado, 23 de noviembre de 2013

Creación de complementos. Paso 1: relatividad

En el post anterior conté algo sobre algunos problemas que aparecían al querer utilizar bibliotecas externas en un proyecto de ZinjaI, y expliqué la solución a un ejemplo paso por paso. El ejemplo se basaba en la biblioteca OpenCV en su versión para Windows. Si siguieron más o menos esos lineamientos, deberían poder compilar un programa básico con OpenCV y verlo corriendo. En ese caso tuvimos que, además de configurar el proyecto, compilar la biblioteca.

En este segundo post vamos a reacomodar esos archivos de la biblioteca, para tener lo justo y necesario en una sola carpeta, carpeta que estará dentro de la carpeta de instalación de ZinjaI para evitar andar desparramando más archivos por el sistema, y para que además podamos llevarla a cualquier otra PC y sin importar dónde se halla instalado ZinjaI en esa otra PC, el proyecto compile igual sin cambios. Todavía se podrán ajustar más detalles muy útiles (como el autocompletado por ejemplo) antes de tener todo listo para armar finalmente la plantilla y el complemento, pero eso quedará para una tercera parte.

martes, 19 de noviembre de 2013

Creación de complementos. Paso 0: configurar un proyecto

Alguien en el foro preguntó cómo hacer para utilizar OpenCV (una biblioteca con todo tipo de utilidades para cuestiones relacionadas a la visión computacional y bastante popular por estos días) en ZinjaI y en Windows. Alguna vez ya escribí de forma genérica acerca de cómo configurar un proyecto en ZinjaI para utilizar una biblioteca. Eso sigue siendo bastante cierto, pero el detalle del cambio de ABI del compilador que comenté en este otro post complicó las cosas. Y aún sin ese problema, las instrucciones aquellas son solo para compilar, pero nos vendría bien también armar una plantilla de proyecto, tener un índice de autocompletado, tal vez acceso a la referencia, etc. Entonces hoy voy a tomar el caso de OpenCV como ejemplo y contar paso a paso cómo armar todo eso y empaquetarlo en un complemento para instalar en ZinjaI en dos pasos. Espero que con este ejemplo los usuarios más interesados se animen a amar sus propios templates, autocompletados, o hasta complementos para compartir con los demás usuarios de ZinjaI.

martes, 8 de octubre de 2013

Exportar un pseudocódigo a un lenguaje real

Desde hace muchísimo tiempo, PSeInt tiene la opción para exportar un pseudocódigo a C++. Es decir, para generar un código C++ que haga exactamente lo mismo que hace un algoritmo en pseudocódigo al ejecutarse en PSeInt. No siempre es posible, pero en general se puede obtener una buena aproximación. El objetivo de esta funcionalidad es bastante dudoso. Definitivamente no está pensado para que generen a través de PSeInt programas reales (es decir, para no tener que aprender un lenguaje real, sino hacerlo acá y convertirlo). Está pensado para servir como ayuda cuando el estudiante empieza a aprender un lenguaje real, luego de haber adquirido lo básico mediante el pseudocódigo. Para generar una sintonía entre lo que ya conoce y lo que está aprendiendo.

El único motivo por el cual se convierte a C++ y no a otro lenguaje es porque C++ es el lenguaje que domino bien, en el cual me siento cómodo, y del cual creo conocer lo suficiente como para decidir cómo conviene hacer las traducciones. Pero muchos docentes que utilizan PSeInt para comenzar, luego pasan a otros lenguajes, y me gustaría que PSeInt también pudiera exportar a muchos de esos otros. En este post voy a contar un poco cómo espero lograrlo, solicitando la colaboración de los docentes (o usuarios en general) que tengan gran conocimiento de esos otros lenguajes para proporcionar ejemplos, y voy a hablar también de los problemas y desafíos que esta traducción supone.

jueves, 26 de septiembre de 2013

Variables de entorno, shells y scripts en GNU/Linux

Estoy tratando de agregar algunas opciones a ZinjaI para poder controlar la forma en que ejecuta los programas que compila. Actualmente, gracias a los toolchains alternativos se puede modificar por completo la forma en que se compila un proyecto (utilizando un makefile personalizado, o hasta un script). Ahora quiero poder hacer algo parecido con la ejecución, pero aquí hay ciertos detalles interesantes a tener en cuenta. ¿Para qué serviría esto? Algunos ejemplos son casos donde lo que ZinjaI compila es parte de algo más grande y lo que en realidad hay que ejecutar es ese algo (como los organismos para la comvida por ejemplo). En otros casos hay que correr el ejecutable a través de una herramienta (por ejemplo al utilizar mpi para paralelizar, a través de mpirun). Pero el caso más útil será cuando simplemente se quiera hacer algo antes de la ejecución, como borrar/crear archivos, o definir variables de entorno, para luego ejecutar normalmente. El problema es que hay algunas particularidades de cómo se lanzan nuevos procesos hijos desde un proceso padre en GNU/Linux, y de cómo se gestionan los entornos en los shells que interpretan los scripts, que me han dado más de un dolor de cabeza. Finalmente llegué a una forma muy simple de hacer más o menos lo que quería, forma que no pude encontrar buscando en Google, y por eso vengo a comentarla.

jueves, 19 de septiembre de 2013

Getters y setters automágicos en C++

Hablando con un amigo y colega hace unos días, me comentaba que en Haxe, un lenguaje con varias cosas tomadas (aparentemente) de actionscript y javascript, se pueden definir atributos con getters y setters en una linea como esta: "public var(A,B)", donde A y B pueden ser "null" si no queremos que se puedan ver o modificar desde fuera de la clase, "default" si queremos que se pueda como si fueran públicos, "get" o "set" si más abajo queremos implementar un getter o setter especial, y otras variantes. Algo interesante de esto es que desde el programa/función "cliente" de la clase (el que la usa para algo mediante su interfaz pública), el acceso a estos atributos no cambia de un caso a otro, sino que es siempre igual, como si fueran públicos. Pero en realidad se mete en medio (si queremos) de forma transparente el getter/setter propio.

A esta clase de cosas que parecen pero no son simples atributos públicos, muchos lenguajes las llaman propiedades. Inmediatamente me acordé de las clases para representar widgets en las ventanas con Borland Builder, donde podía hacer edit1->text="hola" en lugar de edit1->SetText("hola") sin problemas. Y dije: "esto se puede hacer igual de transparente en C++". En el caso de objetos de una interfaz gráfica, hay varias formas de que parezca transparente, pero mi idea era generalizarlo, y plantear algún mecanismo para lograr esto con cualquier atributo sin meter mucho ruido en el código de la clase.

lunes, 9 de septiembre de 2013

Sobre la Programación Orientada a Objetos

Me crié (hablando de programación) con Basic, y con uno de los viejos, donde había que ponerle a todo números de lineas y no teníamos subs. Eso hizo que mi forma de pensar un código fuera fuertemente "estructurada". Más tarde, alguien me sugirió QBasic como una forma de hacer lo mismo que hacía en Basic (el mismo código) pero con un editor más bonito. Explorando qué más tenía QBasic encontré las subs (funciones o subrutinas) y eso me hizo un poco más modular. Cuando pasé a VisualBasic, mi forma de pensar no cambió. La poca y bizarra orientación a objetos de los primeros VB pasó totalmente desapercibida para mí, y sólo incorporé el concepto de evento.

Con ese background (que llevó varios años y estaba bien acentado), entré a la universidad y me dispararon directamente con la Programación Orientación a Objetos (POO) y bastante de C++. Además, era el primer año que la materia se daba en C++; los docentes eran muy buenos programadores con Pascal/Delphi, y tuvieron que aprender C++ solo para actualizar la materia. Todo esto y más hicieron que la orientación a objetos parezca algo forzada. Y si bien no la cuestioné de entrada, tampoco la entendí ni aproveché tanto en mis primeros proyectos. Solo para la parte visual parecía realmente tener sentido.

domingo, 1 de septiembre de 2013

Exprimiendo mejor al Diagrama de Flujo

Con la verificación de sintaxis en tiempo real, una mejor sincronización con la ayuda rápida, las plantillas de estructuras de control de la derecha, y la lista de funciones y operadores de la izquierda, el autocompletado y los tooltips, el indentado inteligente, y algunos otros detalles, creo que la interfaz para escribir un algoritmo en pseudocódigo en PSeInt está bastante bien encaminada y completa. La que no está taaan completa es la de edición de diagramas de flujo, ya que hasta hace poco, si bien se podía editar el diagrama y mandar a ejecutar directamente desde ese editor, tenía varias falencias. Por ejemplo, si había errores de sintaxis, había que volver al pseudocódigo para ver cuales eran y dónde estaban, o si se quería hacer un seguimiento paso a paso también. Estas cosas están cambiando, y en este post les cuento las novedades (a nivel usuario) que ya están listas en el repositorio, y también los cambios de diseño interno (a nivel desarrollador) que tengo que analizar antes de seguir en esta linea.