x
1

Expresión lambda



En el ámbito de la programación, una expresión lambda, también denominada función lambda, función literal o función anónima, es una subrutina definida que no está enlazada a un identificador. Las expresiones lambda a menudo son argumentos que se pasan a funciones de orden superior, o se usan para construir el resultado de una función de orden superior que necesita devolver una función.[1]​ Si la función solo se usa una vez o un número limitado de veces, una expresión lambda puede ser sintácticamente más simple que usar una función con nombre. Las funciones lambda son muy comunes en los lenguajes de programación funcional y en otros lenguajes con funciones de primera clase, en los que cumplen el mismo papel para el tipo de función que los literales para otros tipos de datos.

Las funciones lambda se originaron debido al trabajo de Alonzo Church en su cálculo lambda ─en el que todas las funciones eran anónimas─ en 1936, antes de la invención de las computadoras electrónicas.[2]

En varios lenguajes de programación, las funciones anónimas son introducidas bajo el nombre lambda y generalmente también son referidas como lambdas y abstracciones lambda. Las funciones anónimas han sido un aspecto integrado de los lenguajes de programación desde el origen del lenguaje Lisp en 1958, y un número creciente de lenguajes de programación admite funciones anónimas.

Las funciones anónimas son una forma de funciones anidadas al permitir el acceso a variables ─no locales─ dentro de la función contenedora. Esto significa que las funciones anónimas necesitan ser implementadas utilizando clausuras o closures.

A diferencia de las funciones nombradas anidadas, las funciones anónimas no pueden ser recursivas sin la asistencia de un operador de punto fijo o enlazarlas a un nombre.[3]

Las expresiones lambda pueden ser utilizadas para contener funcionalidades que no necesitan ser nombradas y normalmente se utilizan en un tiempo corto. Algunos ejemplos notables incluyen las clausuras y la currificación.

El uso de expresiones lambda es un tema de estilo. Usar expresiones lambda como la única forma de resolver un problema es erróneo; cada expresión lambda puede en su lugar ser reemplazada por una función nombrada y llamada por su nombre. Algunos programadores utilizan las expresiones lambda para encapsular código específico y no reutilizable para así evitar código basura con muchas pequeñas funciones de pocas líneas.

En algunos lenguajes de programación, las expresiones lambda normalmente son implementadas con propósitos específicos como la vinculación de eventos a devoluciones de llamada, o instanciar la función para valores particulares, lo que puede ser más eficiente, más legible, y menos propenso a errores que llamar a una función de nombre más genérico. El código en las siguientes secciones está escrito en Python 2.x.

Al intentar ordenar de una manera no estándar, puede ser más fácil contener la lógica de comparación como una expresión lambda en lugar de crear una función con nombre. La mayoría de los lenguajes de programación proporcionan una función de clasificación genérica que implementa un algoritmo de ordenación que puede ordenar objetos arbitrarios.

Esta función normalmente acepta una función de comparación arbitraria a la cual se le suministra dos elementos, la función indica si estos son iguales o si uno es mayor o menor que el otro (usualmente se indica mediante la devolución de un número negativo, cero o un número positivo). Considere clasificar una lista de cadenas por la longitud de la cadena:

La función anónima en este ejemplo es la expresión lambda:

La función anónima acepta dos argumentos, x e y , y devuelve la comparación entre ellos utilizando la función incorporada cmp(). Otro ejemplo sería la clasificación de elementos en una lista por el nombre de su clase (en Python, todo tiene una clase):

Nótese que 11.2 tiene nombre de clase "float", 10 tiene nombre de clase "int", y "'number'" tiene nombre de clase "str". El orden ordenado es "float", "int", luego "str".

Las clausuras son funciones evaluadas en un entorno que contienen variables ligadas. El siguiente ejemplo vincula la variable "threshold" (umbral) en una función anónima que compara la entrada con el umbral.

Esto se puede utilizar como una especie de generador de funciones de comparación:

Sería poco práctico crear una función para cada función de comparación posible y puede ser demasiado inconveniente para mantener el umbral alrededor para su uso posterior. Independientemente de la razón por la que se utiliza una clausura, la función anónima es la entidad que contiene la funcionalidad que hace la comparación.

Currificación es el proceso de cambiar una función para que tome menos entradas (en este caso, transformar una función que realiza la división por cualquier número entero en uno que realiza la división por un entero ya establecido).

Si bien el uso de funciones anónimas quizás no es común en la currificación, de todas formas se puede utilizar. En el ejemplo anterior, el divisor de funciones genera funciones con un divisor especificado. Las funciones mitad y tercio currifican la división utilizando un divisor fijo. La función del divisor también forma una clausura al vincular la variable "d".

Python 2.x incluye varias funciones que toman funciones anónimas como argumento. Esta sección describe algunos de ellos.

La función de mapeo realiza una llamada de función en cada elemento de una lista. El siguiente ejemplo se aplica el cuadrado a cada elemento de una matriz con una función anónima.

La función anónima acepta un argumento y lo multiplica por sí mismo (calcula su cuadrado). La forma anterior es desaconsejada por los desarrolladores del lenguaje, quienes sostienen que la forma presentada a continuación tiene el mismo significado y está más alineada con la filosofía del lenguaje:

La función de filtro devuelve todos los elementos de una lista que al ser evaluados utilizando una determinada función regresan True.

La función anónima comprueba si el argumento que se le pasa es par. La solución utilizando la estrategia de mapeo a continuación se considera más apropiado:

La función de doblar / reducir se ejecuta sobre todos los elementos de una lista (normalmente de izquierda a derecha), acumulando un valor a medida que pasa. Un uso común de esto es combinar todos los elementos de una lista en un valor, por ejemplo:

Esto realiza:

La función anónima aquí es la multiplicación de los dos argumentos. El resultado de una función doblar debe ser más de un solo valor. En su lugar, tanto el mapa como el filtro pueden crearse utilizando la función doblar. En el mapeo, el valor que se acumula es una nueva lista, que contiene los resultados de aplicar una función a cada elemento de la lista original. En el filtro, el valor que se acumula es una nueva lista que contiene solo los elementos que coinciden con la condición dada.

A continuación se muestra una lista de los lenguajes de programación más populares que admiten funciones anónimas totalmente, parcialmente como alguna variante, o no lo admiten en lo absoluto. Esta tabla muestra algunas tendencias generales. En primer lugar, los idiomas que no admiten funciones anónimas (C, Pascal, Object Pascal) son todos lenguajes estatisticamente tipificados convencionales. Sin embargo, los lenguajes de tipo estático pueden admitir funciones anónimas. Por ejemplo, los lenguajes de marcas están escritos de forma estática y además incluyen funciones anónimas, y Delphi, un dialecto de Object Pascal, se ha extendido para soportar funciones anónimas. En segundo lugar, los idiomas que tratan las funciones como funciones de primera clase (Dylan, Haskell, JavaScript, Lisp, Lenguaje de marcado, Perl, Python, Ruby, Scheme) generalmente tienen soporte de funciones anónimas para que las funciones se puedan definir y pasar tan fácilmente como otros tipos de datos. Sin embargo, el nuevo estándar C++ 11 los añade a C++, a pesar de que este es un lenguaje convencional estáticamente tipado.

Numerosos idiomas soportan funciones anónimas, o son capaces de realizar alguna función similar.

La función anónima no es compatible con el lenguaje de programación C estándar, pero es soportada por algunas variables de C, como GCC y Clang.

El GNU Compiler Collection (colección de compiladores GNU) (GCC) admite funciones anónimas, mezcladas con funciones anidadas y expresiones de sentencia. Tiene la forma:

El siguiente ejemplo funciona solo con GCC. Debido a cómo se expanden las macros, l_body no puede contener comas fuera de los paréntesis; GCC trata la coma como un delimitador entre argumentos de macro. El argumento l_ret_type puede eliminarse si está disponible __typeof__; En el ejemplo siguiente al usar __typeof__ en un array, este devolverá testtype *, el cual puede ser dereferenciado para el valor real en caso de ser necesario.

Clang soporta funciones anónimas, son llamadas bloques, los cuales tienen la forma:

El tipo de los bloques anteriores es return_type (^)(parameters). Utilizando la extensión de "bloques" anteriormente mencionada y el Grand Central Dispatch (libdispatch), el código podría parecer más simple:

El código con bloques debe ser compilado con el parámetro -fblocks y enlazado con -lBlocksRuntime.

C++11 soporta funciones anónimas, llamadas expresiones lambda , que tienen la forma:

Un ejemplo de función lambda se define de la siguiente forma:

C++11 también soporta clausuras.Las clausuras se definen entre corchetes ([ y ]) en la declaración de la expresión lambda. El mecanismo permite que estas variables sean capturadas por valor o por referencia. La siguiente tabla muestra esto:

Las variables capturadas por valor son constantes por defecto. Agregar mutable después de la lista de parámetros hace que no sean constantes. Los dos ejemplos siguientes demuestran el uso de una expresión lambda:

Esto calcula el total de todos los elementos de la lista. La variable total se almacena como parte de la clausura de la función lambda. Puesto que es una referencia a la variable stack total, esta puede cambiar su valor.

Esto hará que total sea almacenado como referencia, pero value será almacenado como una copia. La captura de this es especial. Solo se puede capturar por valor, no por referencia. this solo se puede capturar si la función de clausura más cercana es una función de tipo no estática. La expresión lambda tendrá el mismo acceso que el miembro que lo creó, en términos de miembros protegidos y privados. Si this es capturado, ya sea explícita o implícitamente, también se comprueba el alcance de los miembros de clase incluidos. Acceder a los miembros de this no necesita el uso explícito de la sintaxis this ->.

La implementación interna específica puede variar, pero la expectativa es que una función lambda que capture todo por referencia almacenará el puntero de pila real de la función en la que se crea, en lugar de referencias individuales a las variables de pila. Sin embargo, debido a que la mayoría de las funciones lambda son pequeñas y locales en el ámbito, son candidatos probables para expansión inline, y por lo tanto no necesitan almacenamiento añadido para las referencias.

Si se invoca un objeto de clausura que contiene referencias a variables locales después del alcance del bloque más interno de su creación, el comportamiento es indefinido.

Las funciones Lambda son objetos de función de un tipo dependiente de la implementación; El nombre de este tipo solo está disponible para el compilador. Si el usuario desea tomar una función lambda como un parámetro, el tipo debe ser una plantilla, o debe crear un std::function o un objeto similar para capturar el valor lambda. El uso de la palabra clave auto puede ayudar a almacenar la función lambda

A continuación se muestra un ejemplo de almacenamiento de funciones anónimas en variables, vectores y matrices; Y pasarlos como parámetros nombrados:

Una expresión lambda con una especificación de captura vacía ([]) puede ser convertida implícitamente en un puntero de función con el mismo tipo que el lambda. Así que esto es legal:

Las bibliotecas Boost también proporcionan su propia sintaxis para las funciones lambda, utilizando la siguiente sintaxis:[11]

D utiliza delegados en línea para implementar funciones anónimas. La sintaxis completa para un delegado en línea es:

Si no es ambiguo, se puede omitir el tipo de retorno y la palabra clave delegate.

Desde la versión 2.0, D asigna clausuras en la pila a menos que el compilador pueda probar que es innecesario; La palabra clave scope se puede utilizar para forzar la asignación de pila. Desde la versión 2.058, es posible utilizar la notación abreviada:

Una función anónima puede asignarse a una variable y utilizarse de la siguiente manera:

Dart permite funciones anónimas en la siguiente forma:

o

Delphi introdujo funciones anónimas desde la versión 2009.

Elixir usa las clausuras (fn) para designar funciones anónimas.

Erlang utiliza una sintaxis para funciones anónimas similar a la de las funciones nombradas.

Go soporta funciones anónimas.

Haskell usa una sintaxis concisa para funciones anónimas (expresiones lambda).

Las expresiones Lambda están totalmente integradas con el motor de inferencia de tipo, y soportan toda la sintaxis y características de las funciones "ordinarias" (excepto el uso de múltiples definiciones para la correspondencia de patrones, ya que la lista de argumentos solo se especifica una vez).

Las siguientes expresiones son todas equivalentes:

En Haxe, las funciones anónimas son llamadas expresiones lambda, y utilizan la sintaxis (argumento-lista) expresión;.

Java desde el JDK 8 soporta funciones anónimas, denominadas Expresiones Lambda.[12]​ Una expresión lambda consiste en una lista separada por comas de los parámetros formales encerrados entre paréntesis, un símbolo de flecha (->) y un cuerpo. Los tipos de datos de los parámetros siempre se pueden omitir, al igual que los paréntesis si solo hay un parámetro. El cuerpo puede consistir en una sentencia o un bloque de sentencia.[13]

Las expresiones Lambda se convierten en "interfaces funcionales" (definidas como interfaces que contienen solo un método abstracto además de uno o más métodos predeterminados o estáticos[13]​), como en el ejemplo siguiente:

En este ejemplo, se declara una interfaz funcional denominada IntegerMath. Las expresiones Lambda que implementan IntegerMath se pasan al método apply() para ejecutarse. Los métodos predeterminados como swap definen métodos en funciones. Java 8 introdujo otro mecanismo denominado referencia de método (el operador ::) para crear una expresión lambda en un método existente. Una referencia de método no indica el número o los tipos de argumentos porque estos se extraen del método abstracto de la interfaz funcional.

En el ejemplo anterior, la interfaz funcional IntBinaryOperator declara un método abstracto int applyAsInt(int, int), por lo que el compilador busca un método int sum(int, Int) en la clase java.lang.Integer.

Las expresiones lambda en Java 8 poseen las siguientes limitaciones:

JavaScript/ECMAScript permite el uso de funciones anónimas.

En ES6:

Esta construcción se utiliza a menudo en Bookmarklets. Por ejemplo, para cambiar el título del documento actual (visible en la barra de título de su ventana] a su URL, el siguiente bookmarklet puede parecer que funciona.

Sin embargo, como la sentencia de asignación devuelve un valor (la propia URL), muchos navegadores crean una nueva página para mostrar este valor. En su lugar, una función anónima, que no devuelve un valor, se puede utilizar:

La sentencia de la función en el primer par de paréntesis (el paréntesis más externo) declara una función anónima, que se ejecuta cuando se utiliza con el último par de paréntesis. Esto es casi equivalente a lo siguiente, que puebla el entorno con f a diferencia de una función anónima.

Se utilizan "Bookmarklets" para evitar nuevas páginas para funciones anónimas arbitrarias: La sentencia de función en el primer par de paréntesis (el más externo) declara una función anónima, que se ejecuta cuando se utiliza con el último par de paréntesis. Esto es casi equivalente a lo siguiente, que completa el entorno con f a diferencia de una función anónima.

Uso de "Bookmarklets" para evitar crear nuevas páginas para funciones anónimas arbitrarias:

O simplemente:

JavaScript posee ciertas sutilezas sintácticas para la semántica de definir, invocar y evaluar funciones anónimas. Estos matices subliminales son una consecuencia directa de la evaluación de las expresiones entre paréntesis. Las siguientes construcciones que se llaman expresiones de funciones inmediatamente invocadas ilustran esto:

y

representando "function(){ ... }" por f La forma de los constructores son un entre paréntesis dentro de un entre paréntesis (f()) y un entre paréntesis aplicado a un entre paréntesis (f)(). Hay que observar que la ambigüedad sintáctica general de una expresión entre paréntesis, argumentos entre paréntesis a una función y los paréntesis alrededor de los parámetros formales en una definición de función. En particular, JavaScript define el operador , en el contexto de una expresión entre paréntesis. No es mera coincidencia que las formas sintácticas coincidan para una expresión y los argumentos de una función (ignorando la función de la sintaxis del parámetro formal). Si f no se identifica en las construcciones anteriores, estas se convierten en (()) y ()(). La primera no proporciona ninguna pista sintáctica de ninguna función residente, pero la segunda debe evaluar la primera entre paréntesis como una función para ser JavaScript legal. El () podría ser ([], {}, 42, "abc", function() {}) siempre que la expresión se evalúe como una función. Además, una función es una instancia de objeto (de la misma manera los objetos son instancias de función) y los corchetes de notación de literal de objeto ({}) se utilizan para definir código reforzado, (en contraposición a usar new Function(...)). En un sentido muy amplio no riguroso (especialmente desde que los enlaces globales están comprometidos), una secuencia arbitraria de afirmaciones reforzadas de JavaScript, {cosas}, puede ser considerada un punto fijo de:

También, se puede escribir más correctamente, pero con precaución de la siguiente forma:

Hay que observar las implicaciones de la función anónima en los fragmentos de JavaScript que siguen:

En el lenguaje de programación Julia se definen las funciones anónimas utilizando la sintaxis (arguments)->(expression),

Lisp y Scheme soportan funciones anónimas utilizando la construcción "lambda", que es una referencia al cálculo lambda. Clojure soporta funciones anónimas con la forma especial fn y la sintaxis del lector #().

Common Lisp tiene el concepto de expresiones lambda. Una expresión lambda se escribe como una lista con el símbolo "lambda" como su primer elemento. La lista contiene entonces la lista de argumentos, la documentación o las declaraciones y un cuerpo de función. Las expresiones lambda se pueden utilizar dentro de las formas lambda y con el operador especial function.

Function se puede abreviar como #. Además, existe la macro lambda, que se expande en una función de forma:

Un uso típico de funciones anónimas en Common Lisp es pasarlas a funciones de orden superior como "mapcar", que aplica una función a cada elemento de una lista y devuelve una lista de los resultados.

La forma lambda en Common Lisp permite que una expresión lambda se escriba en una llamada de función:

También es posible dar nombres globales más adelante a las funciones anónimas en Common Lisp:

Curiosamente, en Scheme (lenguaje de programación), las funciones nombradas son simplemente "azúcar sintáctico" para funciones anónimas vinculadas a nombres:

Se expande (y es equivalente) a:

Clojure soporta funciones anónimas a través de la forma especial "fn":

También hay una sintaxis de lector para definir un lambda:

Al igual que Scheme, las "funciones nombradas" de Clojure son simplemente "azúcar sintáctico" para las lambdas vinculadas a los nombres:

Se expande a:

En Lua (al igual que Scheme) todas las funciones son anónimas. Una "función nombrada" en Lua es simplemente una variable que contiene una referencia a un objeto de función.[14]

Así, en Lua:

Es simple azúcar sintáctico para:

Un ejemplo de uso de funciones anónimas para ordenar en orden inverso:

Las funciones anónimas son importantes en Mathematica. Hay varias maneras de crearlas. A continuación se muestran algunas funciones anónimas que incrementan un número. La primera es la más común. #1 hace referencia al primer argumento y & marca el final de la función anónima

Así, por ejemplo:

Además, Mathematica posee una construcción añadida para realizar funciones anónimas recursivas. El símbolo #0 se refiere a toda la función. La siguiente función calcula el factorial de su entrada:

Las funciones anónimas en MATLAB o Octave se definen mediante la sintaxis @(argumento-lista)expresión. Las variables que no se encuentran en la lista de argumentos se heredan del ámbito de inclusión.

En Maxima se definen funciones anónimas utilizando la sintaxis lambda(argumento-lista,expresión):

Los diversos dialectos de ML (lenguaje de programación) admiten funciones anónimas.

OCaml admite funciones anónimas de la siguiente forma:

F# admite funciones anónimas, de la siguiente manera:

Standard ML admite funciones anónimas, de la siguiente manera:

Perl 5 admite funciones anónimas, en la siguiente forma:

Otras construcciones toman "bloques desnudos" como argumentos, que sirven una función similar a las funciones lambda de un parámetro, pero no tienen la misma convención de paso de parámetros que las funciones. -- @_ no está establecido.

En Perl 6, todos los bloques (incluso aquellos asociados con if, while, etc.) son funciones anónimas. Se ejecuta inmediatamente un bloque que no se utiliza como valor rvalue.

Antes de la versión 4.0.1, PHP no tenía soporte para funciones anónimas.[15]

PHP 4.0.1 introdujo la llamada create_function que inicialmente era cual soportaba las funciones anónimas. Esta llamada de función crea una nueva función con nombre aleatorio y devuelve su nombre como una cadena de texto.

La lista de argumentos y el cuerpo de funciones deben estar en comillas simples, o en su defecto, los signos de dólar deben escaparse. De lo contrario, PHP asume que "$x" significa la variable $x y la sustituirá (a pesar de que posiblemente no exista) en la cadena. Para funciones con comillas o funciones de muchas variables, puede ser muy tedioso asegurarse que el cuerpo de la función prevista es lo que PHP interpreta.

En el ejemplo anterior, cada invocación de create_function crea una nueva función, la cual existe para el resto del programa, y no puede ser recolectada como basura, haciendo que ocupe memoria de forma irreversible en el programa. Si este método se utiliza para crear funciones anónimas muchas veces, por ejemplo, dentro de un bucle, puede causar gaves problemas de memoria.

PHP 5.3 agregó una nueva clase llamada Closure y el "método mágico" __invoke() que hace invocable una instancia de clase. [16]

En el ejemplo anterior, $func es una instancia de Closure y echo$ func() equivale a $func->__invoke $ Z) PHP 5.3 imita las funciones anónimas, pero no admite funciones verdaderamente anónimas porque las funciones de PHP no son objetos de primera clase.

PHP 5.3 soporta clausuras pero las variables deben ser explícitamente indicadas como tales:

La variable $x está enlazada por referencia para al invocar $func este lo modifique y los cambios sean visibles fuera de la función.

Logtalk utiliza la siguiente sintaxis para expresiones anónimas (expresiones lambda):

Un ejemplo simple sin variables libres y usando un predicado de asignación de listas sería:

La currificación también es soportada. Es posible escribir el ejemplo anterior como:

Las funciones anónimas (en general los "predicados" anónimos) se introdujeron en la versión 7.2. de Visual Prolog. [17]​ Los predicados anónimos pueden capturar valores desde el contexto. Si se crea el predicado en un miembro de objeto, este también puede acceder al estado del objeto (captando This), mkAdder devuelve una función anónima, que ha capturado el argumento X en el cierre. La función devuelta es una función que añade X a su argumento:

Python soporta funciones anónimas simples a través de la forma lambda. El cuerpo ejecutable del lambda debe ser una expresión y no puede ser una declaración, la cual es una restricción que limita su utilidad. El valor devuelto por el lambda es el valor de la expresión que está contenida en esta. Las formas Lambda se pueden utilizar en cualquier lugar donde puedan funcionar las funciones ordinarias. Sin embargo, estas restricciones hacen que sea una versión muy limitada de una función normal. Por ejemplo:

En general, las convenciones de Python fomentan el uso de funciones nombradas definidas en el mismo ámbito que uno podría utilizar normalmente funciones anónimas en otros idiomas. Esto es aceptable ya que las funciones definidas localmente implementan todo el poder de las clausuras y son casi tan eficientes como el uso de un lambda en Python.

En el siguiente ejemplo, se puede decir que la función "potencia" (pow) ha sido modificada:

En GNU R las funciones anónimas son definidas utilizando la sintaxis función(argumento-lista)expresión como muestra el siguiente ejemplo:

Ruby soporta funciones anónimas utilizando una estructura sintáctica llamada bloque. Hay dos tipos de datos para bloques en Ruby:

Cuando se pasa a un método, en algunas circunstancias un bloque se convierte en un "Proc".

En Scala, las funciones anónimas utilizan la siguiente sintaxis: [19]

En ciertos contextos, como cuando una función anónima es un parámetro que se pasa a otra función, el compilador puede inferir los tipos de los parámetros de la función anónima y se pueden omitir en la sintaxis. En tales contextos, también es posible utilizar una abreviatura para funciones anónimas que utilizan el carácter de subrayado para introducir parámetros sin nombre.

En Smalltalk las funciones anónimas son llamadas bloques y poseen la siguiente estructura:

En Swift, las funciones anónimas son llamadas clausuras,[20]​ y poseen la siguiente estructura:

Por ejemplo:

En aras de la brevedad y la expresividad, se pueden omitir los tipos de parámetro y el tipo de retorno si pueden inferirse:

Del mismo modo, Swift también soporta declaraciones de devolución implícitas para cierres de una sola declaración:

Finalmente, los nombres de los parámetros también se pueden omitir; Cuando se omiten, se hace referencia a los parámetros utilizando nombres abreviados de argumentos, que consisten en el símbolo $ seguido de su posición (por ejemplo, $0, $1, $2, etc.):

CFML admite cualquier declaración dentro de la definición de la función, no solamente expresiones, además CFML también admite funciones anónimas recursivas:

Las funciones anónimas de CFML implementan clausuras.

En C#, el soporte para funciones anónimas se ha profundizado a través de varias versiones del compilador de idiomas. La versión 3.0 del lenguaje, lanzada en noviembre de 2007 junto a .NET Framework v3.5, soporta completamente las funciones anónimas. En C# son llamadas "expresiones lambda", siguiendo la versión original de funciones anónimas, el cálculo lambda.[21]

Mientras la función sea anónima, no se puede asignar a una variable implícitamente tipada, ya que la sintaxis lambda podría ser una función anónima o un árbol de expresiones, y la elección no puede ser realizada automáticamente por el compilador. Por ejemplo, esto no funciona:

Sin embargo, una expresión lambda puede tomar parte en una inferencia de tipos y puede ser utilizada como un argumento de método, Por ejemplo, para utilizar funciones anónimas con la capacidad de mapeo usando System.Collections.Generic.List (en el método ConvertAll() ):

Las versiones anteriores de C# tenían un soporte más limitado para funciones anónimas. C# v1.0 (introducido en febrero de 2002 junto a .NET Framework v1.0) proporcionó soporte de función anónima parcial mediante el uso de delegados.

Esta construcción es similar a los delegados en PHP. En C# 1.0, los delegados son similares a punteros de funciones que hacen referencia a un método denominado explícitamente dentro de una clase. C# v2.0 (lanzado en noviembre de 2005 junto a .NET Framework v2.0) introdujo el concepto de métodos anónimos como una forma de escribir bloques de declaración sin nombre que se puedan ejecutar en una invocación delegada. C# 3.0 sigue permitiendo estas construcciones, pero también permite la construcción de expresiones lambda.

El siguiente ejemplo está diseñado para ser compilado en C# 3.0 y mostrará las tres formas en las que es posible escribir un método anónimo:

En el caso de la versión 2.0 de C#, el compilador C# toma el bloque de código de la función anónima y crea una función privada estática. Internamente, la función recibe un nombre generado; Este nombre generado se basa en el nombre del método en el que se declara el Delegado. El nombre no está expuesto al código de la aplicación a menos que se utilice reflexión. En el caso de la versión 3.0 de C# , el mismo mecanismo es aplicado.

Visual Basic .NET 2008 introdujo las funciones anónimas a través de la estructura lambda. Combinada con la escritura de tipos implícitos, VB provee una sintaxis sencilla para escribir funciones anónimas.En VB.NET 2008 las funciones anónimas deben ser definidas en una sola línea; no pueden ser expresiones compuestas. Además, una función anónima en VB.NET debe realmente una Function de VB.NET, es decir, debe retornar un valor.

Desde Visual Basic .NET 2010 se es posible definir expresiones lambda multilíneas las cuales además ya no requieren que retornen algún valor. En el siguiente ejemplo se utiliza una función lambda multilinea para definir un Thread.

Es posible utilizar las expresiones lambda en VB.NET dentro de un Task como un "Dispara y corre", permitiendo la ejecución de código de forma asíncrona dentro de un método sincronico.



Escribe un comentario o lo que quieras sobre Expresión lambda (directo, no tienes que registrarte)


Comentarios
(de más nuevos a más antiguos)


Aún no hay comentarios, ¡deja el primero!