En mi último post adelanté algunos aspectos sobre la definición de tipos y gramáticas mediante el uso del lenguaje de modelado M, con el fin de aclarar una duda concreta. No obstante, creo que este post resultará útil a modo de introducción al lenguaje y también como recopilación de enlaces a contenidos interesantes.
En primer lugar, destacar que el lenguaje M es el lenguaje de modelado para Oslo. De hecho, el origen del nombre no es la M de Miguel, sino la M de Modelo. Este lenguaje nos va a permitir llevar a cabo dos tipos de tareas: construir modelos e interactuar con datos. En esta segunda tarea, una de las grandes ventajas del lenguaje M es que se trata de un lenguaje independiente de plataforma. M se centra en proporcionar una serie de construcciones semánticas para definir qué estructuras deben dar forma a nuestros datos, pero abstrae completamente los elementos específicos a cada fuente de datos para llevarlo a cabo.
De forma resumida, podríamos decir que el lenguaje M se fundamenta en tres conceptos:
- Valores: Un valor es un dato que cumple con las reglas y restricciones del lenguaje. Para cualquier sistema o aplicación, existen multitud de valores y relaciones entre ellos, también restricciones. Cuando diseñamos/modelamos un sistema, en esencia estamos definiendo qué tipos de valores podemos encontrar, cómo se relacionan entre ellos y qué restricciones condicionan su comportamiento. Podemos clasificar los valores en lenguaje M en tres categorías fundamentales:
- Simples o escalares: Valores atómicos (no pueden descomponerse en valores más simples). En esta categoría encontramos los tipos intrínsecos del lenguaje (más adelante hablaremos de ellos).
- Colecciones: Repetición de valores o elementos de un mismo tipo (no necesariamente tipos intrínsecos)
- Entidades: Valor compuesto por una o más propiedades, las cuales pueden ser de tipo escalar o compuestas.
- Simples o escalares: Valores atómicos (no pueden descomponerse en valores más simples). En esta categoría encontramos los tipos intrínsecos del lenguaje (más adelante hablaremos de ellos).
- Tipos: Un tipo describe una entidad lógica, compuesta por un nombre determinado y un conjunto de valores. Los tipos en M se pueden clasificar en dos grandes grupos:
- Intrínsecos: Tipos nativos (y escalares) del lenguaje. En esta categoría encontraremos entre otros: Number, Decimal, Integer, Integer32, Date, DateTime, Text…
- Derivados: Declarados por el usuario y compuestos por varios tipos escalares y/o derivados. Normalmente se definen en lenguaje M mediante el uso de la instrucción type.
- Intrínsecos: Tipos nativos (y escalares) del lenguaje. En esta categoría encontraremos entre otros: Number, Decimal, Integer, Integer32, Date, DateTime, Text…
- Extensiones: Una extensión proporciona almacenamiento dinámico para cualquier valor. Pueden derivarse de otros tipos o ser especificadas directamente. En función del ámbito en el cual declaremos la extensión, ésta generará código T-SQL para crear una nueva tabla al compilar el módulo de M, o al instanciar un tipo que la utilice. Por ejemplo, dada la siguiente declaración de un módulo…
1: module Northwind {
2: type Employee {
3: LastName : Text;
4: FirstName : Text;
5: }
6: Employees : Employee*;
7: }
Al compilarlo se generará el siguiente código T-SQL:
1: create table [Northwind].[Employees]
2: (
3: [FirstName] nvarchar(max) not null,
4: [LastName] nvarchar(max) not null
5: );
Sin embargo, también podemos «provocar» la creación de tablas sin necesidad de crear un nuevo tipo, de la siguiente forma:
1: module Northwind {
2: Addresses
3: {
4: {Id=1, Folder=1, State=«NC», Zip=28173},
5: {Id=2, Folder=1, State=«WA», Zip=55555}
6: };
7: }
Dicha construcción en M generará el siguiente código T-SQL:
1: create table [Northwind].[Addresses]
2: (
3: [Folder] int not null,
4: [Id] int not null,
5: [State] nvarchar(max) not null,
6: [Zip] int not null
7: );
8: go
9: insert into [Northwind].[Addresses] ([Id], [Folder], [State], [Zip])
10: values (1, 1, N‘NC’, 28173)
11: ;
12: insert into [Northwind].[Addresses] ([Id], [Folder], [State], [Zip])
13: values (2, 1, N‘WA’, 55555)
14: ;
Por último, y para ser exactos, diremos que M no es tan sólo un lenguaje, sino una serie de características y reglas gramaticales comunes para toda una familia de lenguajes de modelado. Actualmente, disponemos de tres lenguajes específicos, distribuidos con la CTP de Octubre de 2008 de Oslo:
MGraph: Permite serializar datos a estructuras de grafos, con una sintaxis similar a la de lenguajes como JSON. El grafo construido por MGraph es de tipo DAG (Grafo Acíclico Dirigido), el cual proporciona una estructura mejor organizada y eficiente a la hora de ser recorrida que la de un árbol (empleada en lenguajes tipo XML, XAML, etc.)
MSchema: Gramática construida sobre MGraph, cuenta con una serie de esquemas predefinidos para la creación, almacenamiento y cálculo de datos.
MGrammar: También conocido como Mg. MGrammar es un lenguaje para definir lenguajes. Nos proporciona una serie de construcciones para definir gramáticas (de forma similar a como indicábamos en el post anterior) y traducirlas a MGraph.
A través de MGrammar podríamos definir nuestros propios lenguajes, y de hecho ya hay unos cuantos ejemplos desarrollados, que nos permiten definir servicios WCF (MService), máquinas de estados WF, etc.
En próximos posts veremos cómo crear nuevos modelos y lenguajes, compilarlos y almacenarlos en el repositorio de modelos para su posterior uso desde entornos de ejecución .Net (a pesar de que Oslo sirve para modelar sistemas funcionando sobre CUALQUIER entorno de ejecución).
Enlaces relacionados:
- MSDN Oslo Developer Center
- M Language Specification: También disponible «físicamente» en el siguiente libro.
- M Grammar Language Specification