Generación de Código, AjGenesis y AjBasic

En el post que comenté ayer

Sobre la generación de código

el comentador Emmanuel escribía:

Pregunta: Ya que tu apodo es “java” :), porque no utilizar StringTemplate en vez de crear tu propio generador?

http://www.stringtemplate.org/

http://antlr.org/about.html

La respuesta es corta y es larga. Si vieron los ejemplos que he publicado, y cómo funciona AjGenesis:

  • AjGenesis (posts en español con ejemplos)
  • sabrán que he implementado mi propio lenguaje interpretado AjBasic (con una implementación ahora separada en http://code.google.com/p/ajbasic/), que ahora está evolucionando a ser un lenguaje, con el mismo núcleo que el AjSharp:

    AjSharp: un intérprete a la C Sharp, trabajo en progreso

    También está pensado que se pueda utilizar otro lenguaje para los templates:

    Escribiendo templates de AjGenesis en otros lenguajes

    Pero hoy por hoy, se puede usar sólo AjBasic en la generación de código de AjGenesis. Lo adopté, porque pienso que el lenguaje de templates Y DE TAREAS (porque eso tiene AjGenesis, no sólo es templates, sino también contiene código que organiza la generación de artefactos de textos), es tan fundamental en lo que quería construir, que no pensé en montarme sobre otro proyecto. Creo que, pasado el tiempo, ha sido una sabia decisión. Veo que el proyecto actual, tengo un dominio total sobre algo que es parte del núcleo de AjGenesis.

    Recordemos que AjBasic se usa en las tareas. Y permite el uso de objetos dinámicos. Por ejemplo:

    if not Project.Title then

        Project.Title = Project.Name

    end if

     

    if not Project.Version then

        Project.Version = "1.0.*"

    end if

    Este ejemplo, tomado de una tarea típica de los ejemplos que vienen incluidos con el sistema, muestra dos características muy usadas: una, preguntar por Project.Title y si Project o Project.Title no están definidos, eso vale falso para el if (una extensión de ideas de lenguajes anteriores como PHP). Me evito preguntar por Nothing o cosas así. Y otra característica: como Project es un objeto dinámico, le puedo agregar propiedades en cualquier momento.

    También se le pueden sembrar, en el environment (entorno de valores definidos en el sistema en ejecución), objetos .NET “duros”, y el lenguaje los maneja por reflection.

    Esto es algo que todo lenguaje interpretado de hoy en día debería tener: explotación fácil y directa de cualquier framework de clases que lo sostenga. He programado AjBasic de tal forma que podría reimplementarlo fácilmente en Java, usando entonces la librería de clases de Java. Y tiene una estructura (intérprete que ejecuta un árbol abstracto), que puede reimplementarse en cualquier lenguaje en que sea necesario. Por ahora, no he visto la necesidad de hacerlo. Estas razones hacen que no me haya preocupado por compilarlo a bytecodes de la máquina virtual, usando CodeDom, o Emit, porque no es el núcleo de lo que estoy persiguiendo: no necesito velocidad, necesito flexibilidad.

    Otro pequeño e importante detalle:

     

    include "Tasks/Build${Technology.Programming.Dialect}.ajg"

     

    Este tipo de instrucción, de nuevo inspirado en PHP, permite la inclusión dinámica de código. Dependiendo de lo que diga el modelo de tecnología, puedo incluir en la ejecución a Tasks/BuildCSharp2.ajg o a Tasks/BuildJava.ajg o lo que sea, dinámicamente.

    Y en un proyecto actual, del que espero postear en breve, hasta puedo incluir en la expansión de un archivo de template, a otro, dinámicamente:

    Imports System

    Imports System.Collections.Generic

    Imports System.Text

     

    Imports OakLeaf.MM.Main.Business

    Imports OakLeaf.MM.Main.Collections

    Imports OakLeaf.MM.Main.Data

     

    Partial Public Class ${Table.SqlName}

        ''' <summary>

        ''' Hook method automatically executed from the mmBusinessObject constructor

        ''' </summary>

        ''' <remarks></remarks>

        Protected Overridable Sub HookPartialConstructor()

            '' Place code here to be executed when the business object instantiates

        End Sub

     

    <#

        if System.IO.File.Exists("Templates/${Table.Name}PartialVb.tpl") then

            include("Templates/${Table.Name}PartialVb.tpl")

        end if

    #>        

    End Class


    Y tengo más usos para un lenguaje flexible, dentro de AjGenesis. La idea final, es usarlo para tomar decisiones, para convertir el proceso de generación, en un sistema experto. Algunas decisiones ya toma. Por ejemplo, dada un entidad X, que tiene relaciones con otras, puede decidir incluir una página de “ver entidad X” que tenga enlaces o directamente los datos de las entidades con las que se relaciona. O al ver que en el modelo hay entidades, y una de las entidades modela una persona, saber que para mostrar en algun lado (una lista desplegable, una grilla….) a qué persona estamos refiriendo, deberá mostrar nombre, apellido, y tal vez algún de legajo. O que si estoy armando una aplicación distribuida en Java, sepa deducir qué servicios web debo implementar, que DTOs hay que definir, según los casos de usos que estén descriptos en el modelo, y que escriba los ensambladores de esos DTOs.


    Esos sos ejemplos pequeños y grandes de decisiones. Pero la idea es ir avanzando en tener más decisiones, y más reglas, implementadas no con un rígido sistema de reglas forward chaining o backward chaining (que no lo descarto, de ahí mi implementación de AjProlog en curso y de otras ideas), sino ir viendo de explorar la inserción de decisiones en cualquier momento del proceso de generación de código.


    Otro ejemplo: en el proyecto en curso, un sistema real, se implementó con AjBasic/AjGenesis una serie de reglas que examinan la base de datos de desarrollo, y detectan inconsistencias en los nombres de las columnas o relaciones de uno a muchos mal definidas. Y podemos seguir implementando más reglas, que nos avisen de otros problemas.


    Por todo esto, es que no adopté un lenguaje de templates existente: AjGenesis necesitaba, desde su concepción, un lenguaje que fuera más que un lenguaje de templates. Esto me lo hizo ver mis primeros trabajos en el tema, en los 80, cuando implementé algo parecido en C, pero con limitaciones. Y cuando leí en estos años, el libro de Kathleen Dollard Code Generation in Microsoft .NET donde ella no se animaba a implementar un lenguaje, y adoptaba uno existente, como XSLT sobre XML (mala elección), y luego en cada capítulo, tenía que hacer malabares con el modelo, para poder conseguir algún resultado, al leer eso, me decidí por un lenguaje flexible.


    Y no tardé mucho en construir el prototipo. Resultó, como muchas otras veces, divertido! :-)


    Nos leemos!


    Angel “Java” Lopez
    http://www.ajlopez.com/
    http://twitter.com/ajlopez
    http://www.facebook.com/ajlopez

    This entry was posted in 1389, 2643, 3463, 6145, 8596. Bookmark the permalink.

    Leave a Reply

    Your email address will not be published. Required fields are marked *


    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>