Autor en Google+
Saltar al contenido

Variable not found. Artículos, noticias, curiosidades, reflexiones... sobre el mundo del desarrollo de software, internet, u otros temas relacionados con la tecnología. C#, ASP.NET, ASP.NET MVC, HTML, Javascript, CSS, jQuery, Ajax, VB.NET, componentes, herramientas...

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, noticias, curiosidades, reflexiones... sobre el mundo del desarrollo
de software, internet, u otros temas relacionados con la tecnología

¡Microsoft MVP!
miércoles, 1 de abril de 2009
LambdaEntre las múltiples novedades aparecidas con C# 3.0 y VB.NET 9.0, las expresiones lambda son sin duda una de las que en principio pueden parecer más complejas, probablemente por su relación con conceptos no demasiado asimilables como los delegados, inferencia de tipado, métodos anónimos, o tipos genéricos, entre otros.

Sin embargo, esa aparente dificultad desaparece en cuanto se les presta un poco de atención, y una vez comprendidas aportan a los desarrolladores una potencia y agilidad difíciles de lograr con las herramientas disponibles hasta el momento. Sólo hay que ver su amplia utilización dentro del propio .NET framework, LINQ, y nuevas plataformas como ASP.NET MVC, para darse cuenta de su importancia. Y por si fuera poco, según cuentan los expertos, su uso "engancha".

A lo largo de esta serie de tres posts intentaré describir las expresiones lambda desde un punto de vista práctico, con la única pretensión de aportar algo de luz a los que todavía no han sucumbido a su poder. ;-)

El objetivo de este primer post es puramente introductorio, y trataré conceptos y nociones básicas para poder abordar los siguientes. En el segundo post de la serie trataremos las expresiones lambda como funciones anónimas, dejando para el tercero los misteriosos árboles de expresión.

Introducción a las lambda

Según la definición en la Referencia del lenguaje C# de MSDN:
"Una expresión lambda es una función anónima que puede contener expresiones e instrucciones y se puede utilizar para crear delegados o tipos de árboles de expresión"
En la Guía de programación de Visual Basic 9 encontramos otra definición, muy simple y pragmática:
"Una expresión lambda es una función sin nombre que calcula y devuelve un solo valor. Se pueden utilizar las expresiones lambda dondequiera que un tipo de delegado sea válido"
ScottGu también aportó su granito de arena para hacer el concepto más cercano a los desarrolladores; como siempre, al grano:
"Las Expresiones Lambda aportan una sintaxis más concisa y funcional para escribir métodos anónimos."
[...]
"La forma más sencilla para conceptualizar las expresiones lambda es pensar en ellas como formas de escribir métodos breves en una línea."
Partiendo de estas definiciones, y de otras muchas aportadas por Google ;-), está claro que las lambda son funciones, es decir, un conjunto de intrucciones capaces de retornar un valor partiendo de los parámetros que se les suministra, aunque en determinados casos es posible que no reciba ningún parámetro, o que realicen una acción sin retornar nada. Igual que una función tradicional, vaya. Y de hecho, en el cuerpo de una expresión lambda puede haber casi de todo: llamadas a otras funciones, expresiones, bucles, declaraciones de variables...

Sin embargo, a diferencia de los métodos o funciones habituales, las lambdas no necesitan de un identificador, puesto que se declaran in situ, justo en el momento en que van a asignarse a una variable o a utilizarse como parámetro de una función, pasando el destinatario de esta asignación a actuar como delegado, o puntero, hacia la misma, o a ser el contenedor del árbol de expresión que la representa. Ein? Chino, eh? No pasa nada, dentro de poco estudiaremos estos dos usos en profundidad, pero antes vamos a ver cómo se definen las expresiones lambda a nivel de código.

Forma de las expresiones lambda

Las expresiones lambda en C# se escriben según el patrón descrito a continuación, al que le siguen algunos ejemplos que lo ilustran e introducen algunas particularidades.
Forma general: parámetros => expresión, donde:
- parámetros: lista de parámetros separados por comas
- "=>" : separador.
- expresión: implementación de las operaciones a realizar

num => num * 2 // Lambda con un parámetro que retorna
// el doble del valor que se le pasa.


(a, b) => a + b // Lambda con dos parámetros que retorna
// la suma de ambos.


num => { // Lambda con cuerpo que recibe un
int x = new Random().Next(); // entero, y retorna la suma de éste
return num+x; // con un número aleatorio.
}

() => DateTime.Now // Lambda que no recibe parámetros
// y retorna la fecha y hora del sistema.


msg => Console.WriteLine(msg); // Recibe un parámetro, realiza una
// acción y no retorna nada.

 
Como se puede observar, cuando sólo existe un parámetro no es necesario utilizar paréntesis en el lado izquierdo de la expresión, mientras que hay que hacerlo en todos los demás casos. También es interesante destacar que las lambda con cuerpo deben utilizar return para retornar el valor deseado, cuando esto sea necesario.

Y un último dato: fijaos que ni los parámetros ni el retorno de la función tienen indicado un tipo. Aunque puede hacerse, normalmente no será necesario puesto que el compilador podrá inferir (deducir) el tipo a partir de su contexto, más adelante veremos cómo es esto posible. Por tanto, no es necesario escribir código tan extenso como:
  (int a, int b) => (int)(a+b)
 
Y hasta aquí este primer post introductorio. En el siguiente trataremos de explicar el papel de las expresiones lambda como funciones anónimas y facilitadoras del trabajo con delegados.

Publicado en: www.variablenotfound.com.

Estos contenidos se publican bajo una licencia de Creative Commons Licencia Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 España de Creative Commons

2 Comentarios:

Julio Trujillo dijo...

Entonces JM, Crees que podríamos decir que las expresiones Lmbda son una evolución de la palabra clave de C++ "inline", es decir, acoplar un procedimiento en una línea de código dada?

José M. Aguilar dijo...

Hola, Julio. Ante todo, gracias por comentar.

En principio son cosas distintas.

Los "inline" en C++ o C hacen que el compilador intente sustituir cada llamada a la función por el código de la misma para evitar la carga de trabajo adicional que supone realizar dicha llamada, es decir, para optimizar el rendimiento.

En el caso de las lambda, las expresiones son transformadas internamente en funciones a las que se accede a través de sus delegados (la segunda parte del post describe esto). Lo único nuevo que aportan las lambda es la sintaxis mucho menos verbosa para definir estas funciones y sus delegados, además la posibilidad de generar árboles de expresión (tercera parte del post).

Un saludo.