Tuesday, May 20, 2008

Deja Vu

No es la primera vez que tengo esta sensación de haber vivido una y otra vez la misma situación con el desarrollo de software.

Observen la siguiente pantalla:



La imagen superior muestra uno de los tantos procesadores de texto en línea que han surgido últimamente.

Ahora vean la siguiente imagen:



Muestra una "ventana" para la configuración de la página en dicho procesador de texto en línea.


Tenemos dos formas de analizar esta pieza de software, por cierto muchos pensarían que es una excelente obra de ingeniería de software. En la imagen no se puede apreciar, pero el procesador de texto en realidad posee un completo sistema de manejo de ventanas incluyendo arrastre, redimensión en algunos casos, lógica de foco de controles, una multitud de controles de usuario "AJAX" como tabs, combos, barras de herramientas, paneles ocultables, etc.


Si analizamos todo el trabajo que lleva desarrollar una aplicación de este tipo no nos queda más que pensar que estamos en presencia de una buena pieza de software.


Por otro lado, al entrar a dicho procesador de texto en línea, tuve múltiples deja vu simultáneos. Me recordaron cuando implemente un patético sistema de "ventanas" (no móviles por cierto) en QuickBasic usando caracteres en la consola de DOS de 80x25 caracteres ASCII J. Me recordó cuando implemente otro rudimentario sistema de ventana para otra aplicación DOS esta vez en modo grafico usando VGA de 320x200 pixeles a 256! colores simultáneos para un programa de diseño vectorial también en QuickBasic y como cambiaba la paleta de colores usando la INT 10 si mal no recuerdo o capturar las coordenadas del mouse usando los registros AX BX CX y DX por medio la un tanto odiada por mi interrupción 33 (solía no cargar el controlador del mouse en autoexec.bat). También me acorde de otro mini sistema de ventanas hecho ya en una mezcla de C++ y C (nunca olvidare cuando descubrí los punteros a función J que bendición!!!) en el modo VGA de 640x480 y 16 colores, esta vez con ventanas móviles y redimensionables, captura de algunos eventos y unas primitivas para dibujar cubos en 3D en perspectivas ortogonal y logarítmica (perdón por tantos recuerdos :-P). Y al acordarme de todo eso pensé "cuando construí esos primitivos sistemas de ventanas era un adolescente que jugaba programando, sabía nada de ingeniería de software (y no porque piense que ahora se mucho)".

Al ver otro procesador de texto "re-implementado" para la web se me vinieron a la mente multitud de procesadores de texto, sistemas de ventanas, IDEs, planillas de cálculo, juegos, todos re-escritos infinidad de veces hasta el cansancio en diferentes sistemas operativos, entornos de ejecución y plataformas de hardware.


La verdad es que aplicaciones como éste procesador de texto le pueden parecer muy lindas y desarrolladas aplicaciones a los desarrolladores más jóvenes, pero a mí, sólo me recuerdan el estado del arte en la ingeniería de software. Me recuerdan que no somos capaces de reutilizar seriamente ningún desarrollo importante más allá del tiempo de vida de la plataforma de desarrollo original de la aplicación. Me recuerda lo primitivos que somos y cuanto tenemos para crecer en software. Lo cierto es que este tipo de aplicaciones cuando surgen una y otra vez (últimamente los celulares y la web se llevan todos los premios a la reescritura de viejas aplicaciones en nuevos runtimes) no hacen más que mostrarnos que mucho no hemos avanzado como ingenierosJ, o al menos eso me parece.


Si el software es algo abstracto, y un procesador de texto es un procesador de texto se ejecute en DOS, Windows, Linux o en un servidor Web o en un explorador, porque debemos de reescribirlo una y otra vez cada vez que surge un nuevo entorno de ejecución o una nueva serie de librerías de base??


La verdad es que ello no es necesario, simplemente aparentemente a poca gente le preocupa el tema (sobre todo a las grandes empresas proveedoras de software de base parece no importarles jeje), a mi me parece inaceptable si queremos llamarnos verdaderos ingenieros alguna vez en la vida.


En los próximos post "productivos" espero poder empezar a mostrar como con LayerD es posible encarar esta limitación en la ingeniería de software actual y resolver el problema del acoplamiento del software con un API en particular o un entorno de tiempo de ejecución. Con suerte, podré demostrar que el acoplamiento entre software implementado+API+runtime no es necesario y es posible desarrollar software abstracto que siempre posea medios automatizados para ser adaptado a nuevos entornos de tiempo de ejecución o APIs que surjan en el futuro. Así quizás en un futuro no vuelva a tener todos estos deja vu y deje de considerar a nuestra profesión precaria.

Sunday, May 18, 2008

Sobre la palabra “Classfactory” y Mis “colegas” me deprimen

Sobre la palabra "Classfactory" y "Classfactorys"

Aclaraciones importantes detrás de la palabra classfactory y su plural:

  • El singular, es decir si hablamos de una sola clase es "classfactory"
  • El plural, es decir si hablamos de más de una clase es "classfactorys" y esta bien escrito!! no es "classfactories".

¿Por qué se llaman de esa forma?

  • Porque necesitaba un nombre para diferenciar clases "normales" de tiempo de ejecución de clases "de tiempo de compilación". Como normalmente una clase de tiempo de compilación se utilizará para "fabricar código" decidí llamarlas "clases fabricas". Una "clase fabrica" en ingles seria una "factory class" y "clases fabrica" seria "factory classes" (si es que merezco haber aprobado algún curso de inglés básico). Por tanto, decidí llamarla "classfactory" en singular – aquí la humorada es usar palabras en ingles pero orden de sustantivo/adjetivo en español, y usar el plural "classfactorys" porque el singular es "classfactory" que como es una palabra cualquiera inventada para describir una clase de tiempo de compilación, su plural en castellano lo formo agregando una "s" como normalmente haríamos quienes hablamos español, por tanto el plural es "classfactorys" y NO "classfactories".

Si a alguien no le gusta el plural o incluso el singular, está bien, pero sinceramente no me importa es sólo una palabra J.

Mis "colegas" me deprimen

Tal vez soy una persona con demasiado ego, tal vez creo que se demasiado o que soy capaz de ver más que la mayoría – siempre hablando de lo profesional no J. Realmente, me pregunto si es que aunque no me guste soy un profesional tan engreído y tonto. A veces me da miedo pensar las cosas que pienso de algunos "colegas" que tienen muchísima más experiencia, años y conocimientos de los que yo tengo.

Veo muchos profesores muy respetados de mi facultad, profesionales que trabajan en grandes y reconocidas empresas, todas personas que tienen algunos años más que yo y otros muchos más años J, pero la mayoría saben más de algoritmos, de matemáticas, de bases de datos, o de lo que fuera, de lo que yo sé. Todos ellos tienen mucha más experiencia medida en cantidad de trabajos y años de la que poseo.

Sin embargo, no puedo evitar ver los errores que cometen, y pensar "que limitada visión". Me preocupa pensar que todos los profesores que tuve en mi facultad – que no es cualquier facultad – en realidad saben muy poco de ingeniería de software o al menos no lo enseñan. Me preocupa pensar que no son capaces de ver más allá de sus narices y enseñarles a sus alumnos ingeniería de verdad. Me preocupa creer que no tienen la formación ni la visión necesaria para enseñarles a sus alumnos a ser verdaderos ingenieros, para enseñarles a ver con profundidad, para ser críticos. Sinceramente espero equivocarme y que todo ello sólo sea estúpida vanidad mía.

Me preocupa pensar que casi todas las nuevas "tecnologías" de desarrollo que proponen grandes empresas como SUN o Microsoft son deprimentes, patéticas. Después de todo, estas grandes empresas contratan a las personas más "brillantes" para construir lo que nos venden, pero a pesar de ese pensamiento o a causa de ello, me parecen aún más deprimentes.

La verdad, es que la visión que tengo de todos estos profesionales - que el resto de las personas consideran excelentes - personalmente me deprime, me deprime pensar que los profesionales más excelentes que conozco no tienen capacidad visionaria, me deprime ver como los mejores profesores de mi facultad enseñan a construir - lo que para mí son meramente chozas a lo sumo con toque de "sofisticación" - a sus alumnos.

Me da miedo tener tanta vanidad y creer que puedo ver cosas que estos profesionales considerados por todo el mundo excelentes no pueden ver o por lo menos no parecen ver.

Me alivia ver que muchas personas jóvenes que conozco tienen el potencial para cambiar eso y me gusta pensar que cuando todos estos jóvenes sean la mayoría estaré orgulloso de la ingeniería de software, de mi profesión, de mi vocación. Porque la verdad, hoy el estado del arte y la ingeniería me deprime. Y quizás es eso lo que me deprime y no los profesionales quienes son sólo el producto de una profesión poco desarrollada donde todo está por descubrirse.

Dentro de LayerD

Estos días – y para no perder la costumbre – ando muy escaso de tiempo o energías suficientes como para dormir cuatro horas por día :-P. Por tanto, el post será corto cosa que – créanme – no es una de mis características tener capacidad de resumen para bien o para mal.

En el link posteo un PowerPoint que presentamos el año pasado en la UTN-FRC cuando realizamos la primera presentación en sociedad de LayerD (aún sin permitir al público tocar ni siquiera los binarios jeje).

Fueron muy poquitas personas a la presentación lo cual es de esperar teniendo un título para la charla que no es "muy comercial" y la mala difusión que tuvo. Lo importante del PPT que posteo es que habla de muchas cosas las cuales no están documentadas en otro lado – al menos en la web y que recuerde :-P – y si bien sin su "speech" relacionado no todo se entenderá o tendrá sentido, imagino que puede ser útil para comprender la tecnología LayerD.

Recuerdo que dicha charla se había planeado como de una hora y media con un recreíto a la mitad, lo cierto es que fueron tan pocas personas que no queríamos que corrieran en el recreo J y además en ese momento ni lo pensé y seguí hablando sin parar y luego mis compañeros Demian, Lucas y Alejandro. Fue bueno ver que casi nadie se fue antes de terminar – tal vez no se fueron para no dejarnos solos J – a pesar de que hablamos largo rato.

En la charla presentamos varios ejemplos funcionando incluyendo un programa multiplataforma de manejo de archivos que corría sin cambios en Java y NET, una librería activa para conexiones a bases de datos usando ADO.NET, lenguajes de dominio especifico para interfaces gráficas, una estructura para ejecutar fácilmente instrucciones de código en hilos separados, un par de ejemplos en Argentino! (lenguaje LayerD que en este momento se encuentra abandonado lamentablemente), ejemplos de refactoring de código usando classfactorys interactivas, un programa que se corregía a sí mismo si tratábamos de llamar a miembros inexistentes de clases por cometer errores de esctitura, entre otros.

El PPT habla un poco los modulos de salida, de la clasificación de los modulos de salida, de las características principales del lenguaje Zoe y Meta D++, el proceso de compilación de un programa Zoe, los tiempos de compilación. Más importante quizás es que intenta explicar porque necesitamos poder construir software abstracto.

LayerD no es un proyecto pensado o construido a la ligera, no es un lenguaje de programación más, o un generador de código o una utilidad para el programador. Muchas cosas se han tenido en cuenta y se han debido de solucionar para poder hoy empezar a tenerlo funcionando, en cuanto se posean los compiladores y módulos de salida desarrollados al nivel adecuado podrá construirse cualquier tipo de software desde un sistema operativo hasta un blog J, con los compiladores y módulos de salida actuales puede desarrollarse cualquier aplicación .NET J y prontamente Java. Lamentablemente, tengo tan poco tiempo de documentar el proyecto que todos los días me veo superado. Por otro lado, de a poco la falta de documentación va mejorando, ya tengo prácticamente un manual básico de Meta D++ que apenas tenga tiempo de revisar publicare, también estoy trabajando en actualizar la Especificación más formal de Meta D++ (que implícitamente especifica Zoe) y los viejos tutoriales del sitio web. Me alienta saber que si estuvo bien pensado, LayerD debe de resistir el paso del tiempo y lo peor que puede pasar es que alguien más lo reinvente uniendo todas las piezas que une LayerD y quizás realice un mejor trabajo y nos beneficiemos todos.

Quiero cerrar este post tratando de graficar todo lo que LayerD significa y con pocas palabras. Sé que eso es casi imposible porque el proyecto es una visión a mediano y largo plazo para la ingeniería de software, encarnada en herramientas sí, pero no se trata tanto sobre las herramientas sino en cuestionar técnicas, herramientas y formas de solucionar los problemas en la implementación de software. He aprendido que no es sencillo mostrar porque hace falta avanzar en software abstracto, porque LayerD es un camino para llegar a ese objetivo – claro espero no el único – y porque debemos de invertir en ello. Con un poco de suerte y trabajo, espero que en los próximos años quien no use una tecnología similar a LayerD al producir software tenga una gran desventaja competitiva en relación a quienes si lo utilicen y entonces, cuando alguien más visionario lo haya demostrado, el resto comprenderá que no es posible moverse en un mundo de cuatro dimensiones teniendo en cuenta sólo tres o al menos no es posible llegar a todos lados J.

Aquí va el link al PPT.

Friday, May 9, 2008

Inferencia de Esqueleto de Clases a partir de una Rutina Cliente de Ejemplo

Los binarios de LayerD ya estan disponibles para todo el mundo, por tanto comienzo a postear algunos ejemplos. El presente ejemplo es una classfactory un tanto avanzada ya que utiliza varias funciones del CodeDOM de LayerD. Sin embargo, muestra como con classfactorys relativamente simples es posible implementar herramientas que programarlas en IDEs nos llevarían con seguridad bastante más tiempo y sólo nos servirían para ese IDE y lenguaje en particular.

Para probar éste ejemplo baje la última actualización del SDK de LayerD desde SourceForge. El SDK de las semanas anteriores no funcionará.

Los fuentes para la classfactory y el cliente de ejemplo los puede bajar aquí.

Muchas metodologías de programación promueven la escritura en primer lugar de los tests y luego la implementación de las clases y demás artefactos. Entre estas metodologías encontramos las denominadas "Test Driven Development" - Desarrollo Guiado por Pruebas - y los métodos "Agile Programming" - Programación Agíl, o métodos ágiles -.
Muchas otras veces en la medida que utilizamos una clase que nosotros escribimos nos damos cuenta que nos faltaron definir métodos, propiedades, etc.

Si bien, muchos entornos integrados - IDEs - poseen herramientas que permiten escribir la estructura de por ejemplo métodos inexistentes su funcionamiento no siempre es completo o se adecua a lo que necesitamos. Por ejemplo, en Visual Studio 2005 y 2008 podemos pedirle al entorno que escriba el prototipo de un método por nosotros, sin embargo debemos realizar una serie de clics o controles de tecla por cada método faltante, adicionalmente no permite inferir otras construcciones faltantes en clases como propiedades o indexadores.
Por tanto, dependiendo del entorno que poseamos y las capacidades "RAD" de dicho IDE tendremos o no hasta cierto punto la funcionalidad necesaria para encarar de una manera productiva este tipo de enfoque "Guiado por Pruebas".

El ejemplo de classfactory interactiva siguiente permite dado un ejemplo de uso inferir gran parte de la estructura pública de una clase incluyendo métodos y propiedades.

Una parte del código de la classfactory interactiva es el siguiente



public interactive class TypeFromSample{
public:
static exp void New(iname void className){
XplClass^ clase = null;
// Search if provided className exists on current namespace
// If class doesn't exists create one, insert on current namespace and return a new call
// to current function
clase = (XplClass^)context.CurrentNamespace.FindNode("/Class[name='" + className.Identifier + "']");
if (clase == null){
clase = writecode{
public class $className{
}
};
// Insert the class on current namespace
context.CurrentNamespace.Children().InsertAtEnd(clase);
// Return a call to this function with same parameter
return writecode( TypeFromSample::New($className) );
}
// Search for al missing members in current function, find member access binary operator expressions
XplNodeList^ items = context.CurrentFunction.FindNodes("/bo[targetMember='?']");
// For each missing member try to infer it.
for (XplBinaryoperator^ op in items){
if (op.get_targetClass().Contains(className.Identifier)){
// Insert the inferred member on target class
clase.Children().InsertAtEnd(CreateFunctionFor(op));
}
}
// Return
return null;
}
...

El método principal es "New" el cual es estático y toma como argumento un "iname", los "inames" permiten tomar como argumento de funciones identificadores, en este caso cualquier identificador incluyendo un identificador no declarado (esto es por ser un "iname void") y retorna una expresión cualquiera.
Lo primero que se realiza es verificar si existe en el espacio de nombres actual una clase con el nombre indicado en el argumento, si no existe inyecta una nueva clase con dicho nombre y retorna una llamada al mismo método con el fin de que el compilador Zoe vuelva a realizar otro ciclo de compilación y al ejecutarse nuevamente la función "New" se posea información semántica parcial sobre la manera en la que el programador intento usar al tipo que queremos inferir su estructura.
Si la clase indicada como argumento ya existe el método procede a buscar todos los accesos a miembros no resueltos, y luego procesa de dichos elementos sólo los que se correspondan con un acceso al tipo de la clase indicada y los procesa uno por uno con la ayuda de la función "CreateFunctionFor".
La función "CreateFunctionFor" de la classfactory utiliza la información de los nodos del CodeDOM para determinar si la expresión padre del acceso a miembro se trata de una llamada a función o de una asignación. Si la expresión padre es una llamada a función infiere los parámetros y tipo de retorno de la función, si es una asignación infiere una propiedad para la clase.

Si el programa cliente de la classfactory es el siguiente:

static int Main(string^[] args){

// Llamanda a Classfactory Interactiva
// para crear el prototipo de una clase a
// partir de un ejemplo de uso
TypeFromSample::New(MyClass);

// Código de ejemplo de uso a partir
// del cual deseo armar el prototipo
// de MyClass
MyClass^ var = new MyClass();
var.Add(1, 2);
var.CurrentValue = "string";
var[2] = "test";
int n;
n = var.HashOf("hola");
n = var.foo(1, "chau", var, args);
return 0;
}

Al compilar el cliente en modo interactivo se inferirá la siguiente estructura para MyClass:

public class MyClass{
void Add(int p1, int p2){
throw new NotImplementedException();
}
string^ property CurrentValue {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
int HashOf(string^ p1){
throw new NotImplementedException();
}
int foo(int p1, string^ p2, Sample::MyClass^ p3, string^[] p4){
throw new NotImplementedException();
}
}

La classfactory "TypeFromSample" puede mejorarse en muchas formas, por ejemplo:
  • Permitiendo inferir indexadores y constructores
  • Inferir todos los tipos faltantes (más de un tipo a la vez)
  • Presentar interfaz de usuario al programador para consultar sobre una desición de inferencia

La classfactory interactiva tiene menos de 100 líneas de código útil y permite implementar la inferencia de una clase de forma más completa que Visual Studio. Al tratarse de una classfactory interactiva en el futuro también podrá utilizarse para cualquier otro lenguaje LayerD de alto nivel que no sea Meta D++.

A diferencia de una herramienta en un entorno intergrado la classfactory funciona de forma completamente independiente de cualquier entorno e incluso de cualquier editor de texto por ser procesada por los compiladores LayerD directamente, por tanto podemos utilizar su funcionalidad aunque programemos con Notepad. También es posible adaptar su comportamiento a lo que nosotros necesitemos, por ejemplo agregando inferencia de constructores, interfaces, métodos de colección, eventos, etc. y el trabajo que realizamos en dicha utilidad no perderá vigencia porque salga un nuevo entorno de desarrollo.

Es preciso notar que en la actualidad no es posible desarrollar nada similar con ningún lenguaje main-stream sin utilizar el modelo de extensión de algún entorno en particular. En su lugar, LayerD permite desarrollar este tipo de herramientas típicas de entornos IDE directamente en el mismo lenguaje en el cual escribimos todos nuestros programas y usando el mismo conocimiento que poseemos del lenguaje y la programación de classfactorys en general sin atarnos a ningún entorno, versión, plataforma o fabricante en particular.