Hoy planeaba a publicar otra cosa, pero necesito hacer catarsis. Ayer recibí dos quejas consecutivas sobre que el instalador del último ZinjaI parecía contener algo malicioso a ojos de algunos antivirus. Es muy poco probable que tal afirmación sea verdad, más abajo les cuento por qué. Y efectivamente no lo era, el antivirus estaba confundido. Pero me resultó muy alarmante descubrir dónde estaba la confusión. Y para colmo la experiencia de uso de un antivirus me pareció inverosímil. Como programador, entiendo el trabajo de locos que requieren y las concesiones que se deben hacer. Pero creo que pasaron la raya, y por mucho. Lo que vi no tiene justificación, prefiero mi PC llena de bichos antes que trabajar así. Ahora les cuento.
viernes, 28 de agosto de 2015
viernes, 21 de agosto de 2015
La zona del programador
Soy de esa clase de personas que les gusta mucho perder invertir tiempo buscaaando y probaaaando herramientas, o peor aún, haciéndose las propias. Y no es raro que se me valla más tiempo y esfuerzo en esa búsqueda o construcción, del que llevaría resolver el problema particular para cuya resolución quiero esa herramienta. Sin ir más lejos, hace muy poquito les conté sobre un error tonto que me llevó a programar dos nuevas funciones en ZinjaI, y que encima al final ni las necesitaba. Este tipo de cosas (el desviarme para buscar, hacer y/o automatizar herramientas y procesos) me ocurre todo el tiempo, y creo que es común en muchísimos programadores. El problema es que cuando uno desarrolla estas herramientas no-indispensables uno tiende a sentirse algo culpable por no trabajar directamente en la solución del problema, sino posponerla por una deformación profesional propia. Si esto también te pasa a vos, mi valioso lector, este post viene a darte algunas excusas para que dejes de sentirte culpable y valores ese trabajo.
lunes, 10 de agosto de 2015
Preguntas frecuentes sobre PSeInt
Hay tres preguntas acerca de las funcionalidades o el futuro de PSeInt que recibo periódicamente una y otra vez, ya sea en los foros, en mi correo, o a veces hasta en persona. Básicamente, sobre PSeInt para Android, sobre PSeInt en otros lenguajes, y sobre el uso de registros/structs en el pseudolenguaje. Les adelanto que son tres cosas que actualmente no están disponibles en PSeInt, pero si siguen leyendo les cuento mejor por qué no, y qué podemos puede hacer al respecto.
jueves, 30 de julio de 2015
ASM caliente para el alma del programador
Depurar programas paralelos es terriblemente complicado. Y cuando uno le suma a eso su propia idiotez el combo se torna mortal. Esta semana perdí dos días completos por culpa de un error de tipeo. Pero, como toda historia para que merezca ser contada debe tener algún lado bueno, en este caso, mis dos días de caza incluyeron el desarrollo de un par de funcionalidades nuevas en ZinjaI. Funcionalidades que al final de cuentas no necesitaba en absoluto para resolver ese problema, pero que en algún momento pensé que sí, y supongo que a futuro ya les daré mejor uso. Se trata de un par de paneles para inspeccionar el código de máquina generado por el compilador, y el estado de los registros internos del procesador durante la depuración. He aquí la anécdota completa y el resultado.
jueves, 23 de julio de 2015
La escencia de la programación de computadores
El gran Brian Kernighan escribió una vez, hace como mil años (circa 1976), la siguiente frase:
Una posible traducción sería: "El control de la complejidad es la esencia de la programación de computadoras." Debo haber leído esta cita por primera vez hace al menos 10 años. En su momento me pareció una más. No eran palabras rimbombantes, ni conceptos extraños. Parecía más bien un punto de vista, una opinión, con algo de cierto, algo de exagerado, como tantas otras. Otras frases me impactaron/gustaron mucho más cuando las leí por primera vez. Sin embargo, con esta pasó algo muy especial. Con el tiempo, muuuy lentamente, a medida que cometía mis propios errores e iba aprendiendo con cada uno de ellos a programar un poquito mejor, me fui dando cuenta de que esa no es una frase más, sino una de las verdades más profundas e indiscutibles que podemos enunciar sobre la programación.
"Controlling complexity is the essence of computer programming."
Una posible traducción sería: "El control de la complejidad es la esencia de la programación de computadoras." Debo haber leído esta cita por primera vez hace al menos 10 años. En su momento me pareció una más. No eran palabras rimbombantes, ni conceptos extraños. Parecía más bien un punto de vista, una opinión, con algo de cierto, algo de exagerado, como tantas otras. Otras frases me impactaron/gustaron mucho más cuando las leí por primera vez. Sin embargo, con esta pasó algo muy especial. Con el tiempo, muuuy lentamente, a medida que cometía mis propios errores e iba aprendiendo con cada uno de ellos a programar un poquito mejor, me fui dando cuenta de que esa no es una frase más, sino una de las verdades más profundas e indiscutibles que podemos enunciar sobre la programación.
miércoles, 8 de julio de 2015
El Para y los diagramas de flujo: ese pequeño gran detalle
jueves, 2 de julio de 2015
Mientras tanto, en... (III)
Van dos meses sin novedades visibles en PSeInt: sin publicar versiones nuevas, sin hacer comentarios en el blog y sin terminar de ponerme al día con el foro. Por el lado de ZinjaI, pasa algo similar (no hay versiones desde hace 4 meses), aunque es más común dado que los cambios en ZinjaI usualmente requieren más tiempo y más pruebas. Y para completar, hace casi un mes que no escribo nada en el blog. En ambos proyectos hemos visto períodos mucho más largos sin novedades, pero no quiere decir que esa situación me simpatice. Me gusta que siempre haya algún movimiento, por mínimo que sea. Y en verdad lo hubo. Tratando de seguir la filosofía "release erale, release often", en breve lanzaré un par de actualizaciones para compartirlos. Mientras tanto, les cuento por dónde pasan los cambios y les adelanto un "trailer" de la próxima release.
viernes, 5 de junio de 2015
std::function: Ya tengo mi (nuevo) martillo
Todos conocen la frase "si solo tienes un martillo, todo te parece un clavo" o alguna variación con la misma idea. A mi, con la programación me pasa algo curioso. Tengo una caja repleta de herramientas de todo tipo, pero cada vez que agrego a la caja un martillo nuevo, todo lo demás se me convierte en clavo. Mi caja está mayormente llena de C++. Diría que casi todo C++03 está en la caja, y que gradualmente he ido agregando herramientas de C++11/14. En algún punto me pasó con eso de SFINAE y los trucos que se podían hacer, y los apliqué por todos lados. En otro momento, agregé a la caja las maravillosas "Variadic Templates" y grité "I have a hammer!", y variadic templates para todos.
Ahora, la funcionalidad de C++11 que se está tornando increíblemente "martillosa", es la aparición de las funciones lambda, y como yapa de la clase auxiliar std::function. Es decir, la posibilidad de crear funciones y clausuras "al vuelo", sin siquiera ponerles tipo ni nombre, y la facilidad que provee la clase std::function para apuntarle a esos pequeños monstruitos sin que nos importen ni preocupen sus especies. En MotoGT 2 están martillando cuanto clavo (y tornillo) se les cruza. Y el resultado es una delicia. Un buen motor puede dar muchas más libertades sin agregar ruido cuando hace uso de estas cosas, y permite al programador ser mucho más productivo.
Ahora, la funcionalidad de C++11 que se está tornando increíblemente "martillosa", es la aparición de las funciones lambda, y como yapa de la clase auxiliar std::function. Es decir, la posibilidad de crear funciones y clausuras "al vuelo", sin siquiera ponerles tipo ni nombre, y la facilidad que provee la clase std::function para apuntarle a esos pequeños monstruitos sin que nos importen ni preocupen sus especies. En MotoGT 2 están martillando cuanto clavo (y tornillo) se les cruza. Y el resultado es una delicia. Un buen motor puede dar muchas más libertades sin agregar ruido cuando hace uso de estas cosas, y permite al programador ser mucho más productivo.
domingo, 31 de mayo de 2015
Las bases de MotoGT 2: overview
Hace un tiempo les comenté que pienso reescribir MotoGT desde cero. Llamo a este proyecto MotoGT 2. Aunque por fuera, al principio será un clon del primer MotoGT con apenas unos pocos detalles nuevos visibles, por dentro la historia es totalmente diferente. El objetivo es obtener una base de código más sólida con la cual experimentar fácilmente agregando y quitando cosas al juego, para que lo que limite su desarrollo sea mi creatividad y mi poca idea de game-design, y no un código complicado y difícil de modificar o mantener.
Entonces, tengo que escribir un pequeño motor de juego. Lo suficientemente general como para que me provea esa flexibilidad. No tan general como para renegar con cosas que no necesito. Con una interfaz de alto nivel para no lidiar con detalles finos de implementación al concetrarme en la lógica del juego. Con capas o subsistemas desacoplados para que, por ejemplo, la biblioteca que use para gráficos y sonido no me condicione la forma de programar esa lógica del juego. Y más, como para que un imprevisto no tire abajo el proyecto.
Entonces, tengo que escribir un pequeño motor de juego. Lo suficientemente general como para que me provea esa flexibilidad. No tan general como para renegar con cosas que no necesito. Con una interfaz de alto nivel para no lidiar con detalles finos de implementación al concetrarme en la lógica del juego. Con capas o subsistemas desacoplados para que, por ejemplo, la biblioteca que use para gráficos y sonido no me condicione la forma de programar esa lógica del juego. Y más, como para que un imprevisto no tire abajo el proyecto.
martes, 26 de mayo de 2015
Constructores privados y std::shared_ptr
Tuve un problema de diseño/implementación con una clase en particular mientras escribía algunas cosas básicas para el nuevo MotoGT, que me resultó muy interesante por lo simple que es el planteo, y por los caminos rebuscados que puede tomar la respuesta. Básicamente quería garantizar que las instancias de una clase particular solo se pudiesen crear por medio de una función auxiliar. La solución habitual es poner el constructor de la clase como privado/protegido y hacer a la clase amiga de la función. Pero esto no es 100% seguro desde algún punto de vista y, por sobretodo, se complica cuando queremos usar std::shared_ptr y std::make_shared con esa clase. Si no se van, les cuento mejor dónde aparece el problema, para qué sirve, y a qué solución llegué.
martes, 19 de mayo de 2015
Problemas con la terminal y el depurador (parte 2)
Empecé el artículo anterior diciendo que iba a mencionar dos problemas con las terminales y la depuración en ZinjaI, pero como se hizo largo describí solo uno. Pues aquí viene el segundo. Es un problema levemente relacionado, muy molesto, pero generalmente inofensivo. Es el mensaje "&warning: GDB failed to set controlling terminal: Operation not permited" que se muestra al comenzar la depuración en GNU/Linux. Desde la versión 7.0 de gdb, muchos IDEs sufren este mensaje, que asusta al usuario inexperto y genera consultas de lo más variadas. Hay miles de hilos al respecto en foros varios en Internet, pero absolutamente ninguna solución. Yo tampoco pude solucionarlo, pero al menos llegué a entenderlo y me convencí de por qué en general no se puede, y qué consecuencias puede traer. Vengo a documentarlo porque leí miles de respuestas, y la mayoría no están ni remotamente cerca de la verdadera causa, y sus consecuencias.
miércoles, 13 de mayo de 2015
Problemas con la terminal y el depurador (parte 1)
Estuve analizando dos diferencias en el comportamiento de la terminal que usa ZinjaI para ejecutar un programa o proyecto entre la ejecución normal y la ejecución para depuración. La primera es que hasta ahora, la terminal donde se ejecuta la depuración se cierra al finalizar el programa, pase lo que pase, y no le hace caso a las opciones de ejecución que pueden decir que espere una tecla, o que no se cierre si el código de salida no es 0. Esto implica que en la mayoría de los casos, si una ejecución en el depurador finaliza como debe, no llegamos a ver los resultados, a menos que nos tomemos el trabajo de poner algún breakpoint al final del main. Tengo solo la mitad de este problema resuelto.
martes, 5 de mayo de 2015
Variables globales otra vez
Ya comenté que pensaba reescribir desde cero MotoGT. También que el no poder predecir/controlar el orden en que se construyen y destruyen las variables globales me trajo serios problemas. Pues bien, dado que en el nuevo MotoGT voy a volver a usar una buena cantidad de variables globales, me vi forzado a repensar el problema. Y finalmente, encontré una buena solución, con la que puedo tener mis queridas y odiadas variables globales, pero puedo además asegurarme de que se creen y destruyan en un orden correcto.
martes, 14 de abril de 2015
La terminal en blanco y una historia de variables globales
En marzo publiqué una actualización de PSeInt, y tardé como 20 días (mayormente por mi culpa, por mi delay con los foros) en notar que a varios usuarios no les funcionaba ni la ejecución básica. Cuando querían ejecutar un algoritmo, la terminal quedaba en blanco; y si querían editar el diagrama de flujo, estaba vacío. Y así algunos problemas más, pero todas cosas gruesas, importantes, absolutamente impresentables.... Y entonces ¿cómo es que subí eso y no me di cuenta? He aquí una historia de variables globales y estáticas en C++, con moraleja conocida: evitarlas a toda costa.
jueves, 9 de abril de 2015
MinGW64 y otras variantes para ZinjaI en Windows
Se supone que ZinjaI está preparado para configurar fácilmente más de un posible compilador. En GNU/Linux, suelo alternar entre gcc y llvm-clang sin problemas. Pero en Windows, el cambio es un poquito más delicado, porque el compilador y demás herramientas afines que están como parte de ZinjaI, y no del sistema. Si bien se suponía que era posible hacerlo de todas formas, y que teóricamente el cambio debía ser simple y directo, de la teoría a la práctica suele haber un buen trecho, y por eso no le tenía plena confianza a esta funcionalidad. Pero hace unos días finalmente lo probé y verifiqué que (muy sorprendentemente) funciona justo como esperaba. Y esto es algo muy bueno, porque ya es hora de empezar a utilizar 64bits. En este post les cuento cómo configurar otro MinGW que no sea el que trae ZinjaI, tomando una versión alternativa de 64bits como ejemplo, qué tiene esto de bueno, y cuáles son por ahora las limitaciones.
Suscribirse a:
Entradas (Atom)