Un ejemplo de Dynamic Expressions

El jueves, estaba preparando una presentación para ayer viernes, explicando cálculo lambda, su historia, su aplicación en lenguajes de programación. Al final de la presentación, mostré cómo las lambdas llegaron a .NET: delegados, notación lambda y expresiones lambda.

Haciendo una rápida búsqueda de enlaces para la charla, encontré esta implementación “cool” de un “parser” de expresiones dinámicas, en el ejemplo:

DynamicLinq.cs

Ese código menciona el post de Scott Guthrie:

Dynamic LINQ (Part 1- Using the LINQ Dynamic Query Library)

El código está incluido en el directorio DynamicQuery en:

C# Dynamic Query Library (included in the -LinqSamples-DynamicQuery directory)

Mi idea inicial para la charla era describir una fórmula y compilarala, usando System.Linq.Expressions. Pero la implementación de arriba, tiene una característica notable: en lugar de construir un árbol de expresiones, paso a paso, creando cada nodo, toma un string y los analiza en el momento, convirtiéndolo a una versión compilada.

OK, este truco es usado por muchas implementaciones de query en Linq, pero no conocía que entre el código de ejemplo de Microsoft estuviera este código.

Usando el DynamicLinq.cs, pude crear una aplicación WinForm, donde la fórmula se ingresa y se compila en el momento:

Vean que podemos usar clases de .NET. “x” es el parámetro que uso como variable en el cálculo de la fórmula.

Este es el código clave en el archivo Calculator.cs:

 

public Delegate CompileFormula(string formula) { ParameterExpression x = Expression.Parameter(typeof(double), "x"); LambdaExpression e = DynamicExpression.ParseLambda(new ParameterExpression[] { x }, null, formula); return e.Compile(); }

El delegado compilado puede ser invocado, proveyendo el valor del parámetro “x”:

 

public double[] Calculate(Delegate formula, double from, double to, double step) { List<double> values = new List<double>(); for (double x = from; x <= to; x += step) values.Add((double) formula.DynamicInvoke(x)); return values.ToArray(); }

Pueden descargar este ejemplo de:


http://code.google.com/p/ajcodekatas/source/browse#svn/trunk/DynamicExpressionsExample


Otra implementación de expresiones dinámicas compiladas:


To Bind or Not To Bind – Dynamic Expression Trees – Part 3 – B# .NET Blog
To Bind or Not To Bind – Dynamic Expression Trees – Part 2 – B# .NET Blog
To Bind or Not To Bind – Dynamic Expression Trees – Part 1 – B# .NET Blog


Algunas ideas a explorar:


- Extender el ejemplo a tres dimensiones (podría usar un ejemplo que viene en F# con DirectX como base)


- Enviar una fórmula como texto, para ser procesada en una aplicación distribuida, grilla, o cluster de HPC. Por ejemplo, la fórmula del fractal a calcular en forma distribuida.


- Code kata escribiendo mi propio .Parse y .Compile para alguno de mis lenguajes de scripting


Si necesitan más poder, el próximo nivel de lenguajes dinámicos y su compilación a .NET, ese el namespace  Microsoft.Scripting dentro del código fuente de IronPython:


http://www.codeplex.com/IronPython/SourceControl


Introducciones a IronPython y la iniciativa DLR:


CLR Inside Out- IronPython and the Dynamic Language Runtime
CLR Inside Out- Dynamic Languages and Silverlight
InfoQ- Microsoft Surpasses Java’s Dynamic Language Support-
CLR Inside Out – IronPython


Enlaces relacionados sobre lambda, Dynamic Language Runtime, y lenguajes dinámicas en general:


http://delicious.com/ajlopez/lambda
http://delicious.com/ajlopez/dlr
http://delicious.com/ajlopez/dynamiclanguages


Nos leemos!


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

This entry was posted in 1389, 5374, 8870. 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>