DSL: Lenguaje de Alto Nivel

Las siglas DSL tienen como signficado domain-specific language (lenguaje específico del dominio). La construcción de un lenguaje específico es algo natural en el ser humano, el lenguaje se adapta al entorno en el que vivimos y al uso que de él hacemos. ¿Sabías que esto mismo es extrapolable a los lenguajes de programación?

Un lenguaje de dominio específico es, a diferencia de los lenguajes de ámbito general, un lenguaje concebido para resolver un cierto tipo de problemas de una forma muy simple, completa, más descriptiva o más rápida.

El DSL se suele emplear mucho en la elaboración de ficheros de configuración, como los de Asterisk (AEL), o los de OpenSIPS, o los de Puppet. También para la elaboración de una funcionalidad acotada como la que ofrecen los VoiceXML, o en sí los protocolos de comunicaciones como el HTTP o XMPP.

¿En qué me puede ayudar un DSL?

La labor de un programador es automatizar a través de código. Un programador de la informática (de la etimología francesa de información automática) se diferencia de un administrativo por la búsqueda de esta automatización, pero no solo a través de la programación solicitada, sino también de su propio trabajo para alcanzar niveles superiores de rendimiento.

El desarrollo de un DSL se puede entender como una jerga que ayuda al programador a realizar sus tareas de forma más rápida. La mayoría de programadores solo modifican el lenguaje dentro de sus límites agregando frameworks y haciendo uso de técnicas avanzadas como decoradores, macros, transformadores o incluso a través de la modificación del funcionamiento para adaptarse a un dato almacenado a través de técnicas como la reflexión.

Una forma más simple es diseñando un DSL. Un lenguaje que aporta semántica y auto-documentación al trabajo a realizar a través del propio lenguaje adaptado únicamente a la necesidad a cubrir. Por ejemplo, si siempre programamos sistemas basados en CRUD, estos se almacenan en la base de datos y tenemos que poder extraer esta información, ¿cómo podríamos simplificarlo a través de un lenguaje de dominio específico?

DEFINE camiones
    matricula TEXT(50)
    tara INTEGER BETWEEN 3500 AND 7000
    color ENUM('rojo', 'negro', 'blanco')

    GET /camiones/:matricula, :query
        RETURN SELECT camiones(:matricula, :query)
    END

    PUT /camiones, :query, :body
        INSERT camiones(:body)
    END

    POST /camiones/:matricula, :query, :body
        UPDATE camiones(:matricula, :query) WITH (:body)
    END

    DELETE /camiones/:matricula, :query
        DELETE camiones(:matricula, :query)
    END
END

Obviamente este lenguaje está acotado a la definición de un modelo de datos, con las reglas que se quieran establecer sobre el modelo de datos para la validación e incluso excepciones que se quieran disparar en caso de que no se cumpla la validación. También está acotado al protocolo HTTP a través de los métodos que se pueden definir y los datos de entrada que se soportan.

Si tu trabajo es realizar sistemas basados en REST para formar parte de un sistema basado en SOA esta construcción te podría llegar a resultar muy cómoda y al alcanzar soltura hasta muy rápida para montar un CRUD completo con creación del modelo en la base de datos y métodos de acceso basados en HTTP.

 Convencido, ¿cómo lo hago?

En la asignatura de lenguajes de programación de la carrera de informática, en la Universidad, se estudian diversas técnicas para poder acometer esta tarea. La técnica más conocida y estudiada es EBNF, basada en BNF, es la notación de Backus-Naur extendida. Es un metalenguaje para poder expresar gramáticas libres. También podemos usar PEG Parsing Expression Grammar que se está extendiendo mucho ahora o GLR Generalized LR para el manejo de gramáticas ambiguas y no deterministas.

Para comenzar puedes elegir uno simple. Yo comencé por EBNF y las herramientas típicas de analizador léxico y analizador sintáctico, pero al tropezar con la primera piedra cambié a PEG y de momento tengo hecho un analizador de SQL y otro analizador de PHP en Erlang.

Si tienes más tiempo y quieres revisar los algoritmos en los que están basados para poder elegir el que mejor se adapte a tus necesidades, en esta página de wikipedia puedes ver cada una de estas cosas.

En el caso de arriba y pensando que elegimos PEG y más en concreto neotoma para desarrollar la solución sobre la máquina virtual de Erlang, podemos escribir nuestro PEG de la siguiente forma:

definition <- 'DEFINE' space key space (vars / methods) space 'END' ~;

key <- [a-zA-Z_] [a-zA-Z0-9_]* ~;
space <- [ \t\n\s\r]+ ~;

vars <- var (space var)+ `
   ...
`;

var <- key space type (space constraint)+ `
   ...
`;

type <- 'INT' / 'TEXT(' [0-9]+ ')' / 'DATE' / 'DATETIME' / enum ~;
text <- 'TEXT(' [0-9]+ ')' `
   ...
`;
enum <- 'ENUM(' space? key space? (',' space? key)* ')' `
   ...
`;
constraint <- between / 'NOT' space 'NULL' ~;
between <- 'BETWEEN' space [0-9]+ space 'AND' [0-9]+ `
   ...
`;

...

Podría hacerlo completo pero aún así se nos quedarían muchas cosas en el tintero. Un DSL tiene la particularidad de que va creciendo y agregando versiones según la necesidad a cubrir y cómo evolucione esta necesidad y así con ella el lenguaje.

 ¿Y la dificultad de aprenderlo?

Aprender un nuevo lenguaje siempre es duro. Hay muchas personas que muestran rechazo, otras intentan ignorarlo. En nuestra mano está el realizar el lenguaje lo sumamente pequeño, simple y útil, para que su uso no se vea como dificultoso o tedioso.

Obviamente, hacer un DSL no constituye el eliminar un lenguaje de ámbito general. El DSL solo sustituye una parte del desarrollo normal, el resto deberá de seguir haciéndolo de la forma en que siempre lo hizo.

Conclusiones

Por mi parte, considero que el enfoque de desarrollar un DSL para simplificar el desarrollo de un sistema es básico. Un DSL nos permite adaptar el lenguaje de programación al lenguaje de dominio y hacer el código más claro para los que no son programadores, pudiendo incluso dar las reglas a estos para desarrollar.

Con el ejemplo expuesto más arriba seguramente muchos habrán notado que algo similar se podría emplear en sus organizaciones y echando un vistazo a los sistemas de gramáticas, los lenguajes en los que se pueden implementar, ya estaréis pensando en cómo hacerlo, ¿dónde lo veis más útil?, ¿cuál es el primer DSL que harías?