stringtranslate.com

Función anónima

En programación informática , una función anónima ( literal de función , expresión o bloque ) es una definición de función que no está vinculada a un identificador . Las funciones anónimas suelen ser argumentos que se pasan a funciones de orden superior o se utilizan para construir el resultado de una función de orden superior que necesita devolver una función. [1] Si la función solo se utiliza una vez, o un número limitado de veces, una función anónima puede ser sintácticamente más ligera que utilizar una función con nombre. Las funciones anónimas son omnipresentes en los lenguajes de programación funcional y otros lenguajes con funciones de primera clase , donde cumplen el mismo papel para el tipo de función que los literales para otros tipos de datos .

Las funciones anónimas se originan en el trabajo de Alonzo Church en su invención del cálculo lambda , en el que todas las funciones son anónimas, en 1936, antes de las computadoras electrónicas. [2] En varios lenguajes de programación, las funciones anónimas se introducen utilizando la palabra clave lambda , y las funciones anónimas a menudo se denominan lambdas o abstracciones lambda. Las funciones anónimas han sido una característica de los lenguajes de programación desde Lisp en 1958, y un número creciente de lenguajes de programación modernos admiten funciones anónimas.

Nombres

Los nombres "abstracción lambda", "función lambda" y "expresión lambda" hacen referencia a la notación de abstracción de funciones en el cálculo lambda, donde la función habitual f ( x ) = M se escribiría x . M ) , y donde M es una expresión que utiliza x . Compárese con la sintaxis de Python de .lambda x: M

El nombre "función flecha" hace referencia al símbolo matemático " maps to ", xM . Compárese con la sintaxis de JavaScript de . [3]x => M

Usos

Las funciones anónimas se pueden utilizar para contener funcionalidades que no necesitan ser nombradas y posiblemente para uso a corto plazo. Algunos ejemplos notables incluyen cierres y currying .

El uso de funciones anónimas es una cuestión de estilo. Su uso nunca es la única forma de resolver un problema; cada función anónima podría definirse como una función nombrada y llamarse por su nombre. Las funciones anónimas suelen proporcionar una notación más breve que la definición de funciones nombradas. En lenguajes que no permiten la definición de funciones nombradas en ámbitos locales, las funciones anónimas pueden proporcionar encapsulación a través de un ámbito localizado, sin embargo, el código en el cuerpo de dicha función anónima puede no ser reutilizable o susceptible de pruebas por separado. Las funciones anónimas cortas/simples utilizadas en expresiones pueden ser más fáciles de leer y comprender que las funciones nombradas definidas por separado, aunque sin un nombre descriptivo pueden ser más difíciles de entender.

En algunos lenguajes de programación, las funciones anónimas se implementan comúnmente para propósitos muy específicos, como vincular eventos a devoluciones de llamadas o instanciar la función para valores particulares, lo que puede ser más eficiente en un lenguaje de programación dinámico , más legible y menos propenso a errores que llamar a una función con nombre.

Los siguientes ejemplos están escritos en Python 3.

Clasificación

Al intentar ordenar de una manera no estándar, puede ser más fácil incluir la lógica de ordenación como una función anónima en lugar de crear una función con nombre. La mayoría de los lenguajes proporcionan una función de ordenación genérica que implementa un algoritmo de ordenación que ordenará objetos arbitrarios. Esta función generalmente acepta una función arbitraria que determina cómo comparar si dos elementos son iguales o si uno es mayor o menor que el otro.

Considere este código Python que ordena una lista de cadenas por longitud de la cadena:

>>>  a  =  [ 'casa' ,  'coche' ,  'bicicleta' ] >>>  a . sort ( key = lambda  x :  len ( x )) >>>  a [ 'coche' ,  'bicicleta' ,  'casa' ]

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

lambda  x :  longitud ( x )

La función anónima acepta un argumento, x, y devuelve la longitud de su argumento, que luego el sort()método utiliza como criterio de clasificación.

La sintaxis básica de una función lambda en Python es

lambda  arg1 ,  arg2 ,  arg3 ,  ... :  < operación  sobre  los  argumentos  que devuelve  un  valor >

La expresión devuelta por la función lambda se puede asignar a una variable y utilizar en el código en varios lugares.

>>>  suma  =  lambda  a :  a  +  a >>>  suma ( 20 ) 40

Otro ejemplo sería ordenar elementos de una lista por el nombre de su clase (en Python, todo tiene una clase):

>>>  a  =  [ 10 ,  'número' ,  11.2 ] >>>  a . sort ( key = lambda  x :  x . __class__ . __name__ ) >>>  a [ 11.2 ,  10 ,  'número' ]

Tenga en cuenta que 11.2tiene el nombre de clase " float", 10tiene el nombre de clase " int" y 'number'tiene el nombre de clase " str". El orden de clasificación es " float", " int" y luego " str".

Cierres

Los cierres son funciones que se evalúan en un entorno que contiene variables vinculadas . El siguiente ejemplo vincula la variable "umbral" en una función anónima que compara la entrada con el umbral.

def  comp ( umbral ):  devuelve  lambda  x :  x  <  umbral

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

>>>  func_a  =  comp ( 10 ) >>>  func_b  =  comp ( 20 )>>>  print ( func_a ( 5 ),  func_a ( 8 ),  func_a ( 13 ),  func_a ( 21 )) Verdadero  Verdadero  Falso Falso >>>  imprimir ( func_b ( 5 ),  func_b ( 8 ),  func_b ( 13 ),  func_b ( 21 )) Verdadero Verdadero  Verdadero  Falso 

Sería poco práctico crear una función para cada función de comparación posible y puede resultar demasiado incómodo mantener el umbral para su uso posterior. Independientemente del motivo por el que se utilice un cierre, la función anónima es la entidad que contiene la funcionalidad que realiza la comparación.

Zurra

Currying es el proceso de cambiar una función de modo que, en lugar de tomar múltiples entradas, tome una sola entrada y devuelva una función que acepte la segunda entrada, y así sucesivamente. En este ejemplo, una función que realiza una división por cualquier número entero se transforma en una que realiza una división por un número entero determinado.

>>>  def  divide ( x ,  y ): ...  devuelve  x  /  y>>>  def  divisor ( d ): ...  return  lambda  x :  divide ( x ,  d )>>>  mitad  =  divisor ( 2 ) >>>  tercio  =  divisor ( 3 )>>>  imprimir ( mitad ( 32 ),  tercio ( 32 )) 16.0  10.6666666666666666>>>  imprimir ( mitad ( 40 ),  tercio ( 40 )) 20.0  13.333333333333334

Si bien el uso de funciones anónimas quizás no sea común en la currificación, aún se puede utilizar. En el ejemplo anterior, la función divisor genera funciones con un divisor especificado. Las funciones half y third currifican la función divide con un divisor fijo.

La función divisor también forma un cierre al vincular la variable d.

Funciones de orden superior

Una función de orden superior es una función que toma una función como argumento o devuelve una como resultado. Esto se usa comúnmente para personalizar el comportamiento de una función definida de manera genérica, a menudo una construcción de bucle o un esquema de recursión. Las funciones anónimas son una forma conveniente de especificar dichos argumentos de función. Los siguientes ejemplos están en Python 3.

Mapa

La función map realiza una llamada a una función en cada elemento de una lista. El siguiente ejemplo eleva al cuadrado cada elemento de una matriz con una función anónima.

>>>  a  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ] >>>  lista ( mapa ( lambda  x :  x * x ,  a )) [ 1 ,  4 ,  9 ,  16 ,  25 ,  36 ]

La función anónima acepta un argumento y lo multiplica por sí mismo (lo eleva al cuadrado). La forma anterior es desaconsejada por los creadores 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:

>>>  a  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ] >>>  [ x * x  para  x  en  a ] [ 1 ,  4 ,  9 ,  16 ,  25 ,  36 ]

Filtrar

La función de filtro devuelve todos los elementos de una lista que evalúan como Verdadero cuando se pasan a una función determinada.

>>>  a  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ] >>>  lista ( filtro ( lambda  x :  x  %  2  ==  0 ,  a )) [ 2 ,  4 ,  6 ]

La función anónima comprueba si el argumento que se le pasa es par. Al igual que con map, se considera más apropiada la siguiente forma:

>>>  a  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ] >>>  [ x  para  x  en  a  si  x  %  2  ==  0 ] [ 2 ,  4 ,  6 ]

Doblar

Una función de plegado se ejecuta sobre todos los elementos de una estructura (en el caso de las listas, normalmente de izquierda a derecha, se denomina "plegado a la izquierda" reduceen Python) y acumula un valor a medida que avanza. Esto se puede utilizar para combinar todos los elementos de una estructura en un solo valor, por ejemplo:

>>>  desde  functools  importar  reduce >>>  a  =  [ 1 ,  2 ,  3 ,  4 ,  5 ] >>>  reduce ( lambda  x , y :  x * y ,  a ) 120

Esto funciona

La función anónima aquí es la multiplicación de los dos argumentos.

El resultado de un pliegue no tiene por qué ser un único valor. En cambio, tanto el mapa como el filtro se pueden crear utilizando el pliegue. En el mapa, 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 aquellos elementos que coinciden con la condición dada.

Lista de idiomas

La siguiente es una lista de lenguajes de programación que admiten funciones anónimas sin nombre en su totalidad, en parte como alguna variante, o no las admiten en absoluto.

Esta tabla muestra algunas tendencias generales. En primer lugar, los lenguajes que no admiten funciones anónimas ( C , Pascal , Object Pascal ) son todos lenguajes de tipado estático. Sin embargo, los lenguajes de tipado estático pueden admitir funciones anónimas. Por ejemplo, los lenguajes ML son de tipado estático e incluyen fundamentalmente funciones anónimas, y Delphi , un dialecto de Object Pascal , se ha ampliado para admitir funciones anónimas, al igual que C++ (por el estándar C++11 ). En segundo lugar, los lenguajes que tratan las funciones como funciones de primera clase ( Dylan , Haskell , JavaScript , Lisp , ML , Perl , Python , Ruby , Scheme ) generalmente tienen soporte para funciones anónimas, de modo que las funciones se pueden definir y pasar tan fácilmente como otros tipos de datos.

Ejemplos

Numerosos lenguajes admiten funciones anónimas o algo similar.

APL

Sólo algunos dialectos admiten funciones anónimas, ya sea como dfns , en el estilo tácito o una combinación de ambos.

 f ​​{ × } Como una función derivada f 1 2 3 1 4 9 g ⊢×⊢ Como un tren tácito de 3 funciones ( bifurcación ) g 1 2 3 1 4 9 h × Como una función tácita derivada h 1 2 3 1 4 9                                  

C (extensión no estándar)

La función anónima no es compatible con el lenguaje de programación C estándar, pero sí con algunos dialectos de C, como GCC [55] y Clang .

CCG

La colección de compiladores GNU (GCC) admite funciones anónimas, combinadas con funciones anidadas y expresiones de instrucciones. Tiene la forma:

( { tipo_de_retorno nombre_de_funciones_anónimas ( parámetros ) { cuerpo_de_función } nombre_de_funciones_anónimas ; } )          

El siguiente ejemplo funciona únicamente con GCC. Debido a la forma en que se expanden las macros, l_bodyno pueden contener comas fuera de los paréntesis; GCC trata la coma como un delimitador entre los argumentos de la macro. El argumento l_ret_typese puede eliminar si __typeof__está disponible; en el siguiente ejemplo, el uso de __typeof__on array devolvería testtype *, que se puede desreferenciar para obtener el valor real si es necesario.

#incluir <stdio.h> //* esta es la definición de la función anónima */ #define lambda(l_ret_type, l_arguments, l_body) \  ({ \  l_ret_type l_anonymous_functions_name l_arguments \  l_body \  &l_anonymous_functions_name; \  })#define forEachInArray(fe_arrType, fe_arr, fe_fn_body) \ { \  int i=0; \  for(;i<sizeof(fe_arr)/sizeof(fe_arrType);i++) { fe_arr[i] = fe_fn_body(&fe_arr[i]); } \ }typedef struct { int a ; int b ; } tipo de prueba ;      void printout ( const testtype * array ) { int i ; for ( i = 0 ; i < 3 ; ++ i ) printf ( "%d %d \n " , array [ i ].a , array [ i ] .b ) ; printf ( " \n " ); }                     int main ( void ) { tipo de prueba matriz [] = { { 0 , 1 }, { 2 , 3 }, { 4 , 5 } };          printout ( matriz ); /* la función anónima se proporciona como función para foreach */ forEachInArray ( testtype , matriz , lambda ( testtype , ( void * item ), { int temp = ( * ( testtype * ) item ) .a ; ( * ( testtype * ) item ) .a = ( * ( testtype * ) item ) .b ; ( * ( testtype * ) item ) .b = temp ; return ( * ( testtype * ) item ); })); printout ( matriz ); return 0 ; }                                       

Sonido metálico (C, C++, Objective-C, Objective-C++)

Clang admite funciones anónimas, llamadas bloques , [56] que tienen la forma:

^ return_type ( parámetros ) { cuerpo_función }      

El tipo de los bloques de arriba es return_type (^)(parameters).

Usando la extensión de bloques antes mencionada y Grand Central Dispatch (libdispatch), el código podría verse más simple:

#include <stdio.h> #include <despacho/despacho.h>  int main ( void ) { void ( ^ bucle_de_conteo )() = ^ { for ( int i = 0 ; i < 100 ; i ++ ) printf ( "%d \n " , i ); printf ( "ah ah ah \n " ); };                   /* Pasar como parámetro a otra función */ dispatch_async ( dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_DEFAULT , 0 ), count_loop );   /* Invocar directamente */ count_loop ();  devuelve 0 ; } 

El código con bloques debe compilarse -fblocksy vincularse con-lBlocksRuntime

C++ (desde C++11)

C++11 admite funciones anónimas (técnicamente, objetos de función ), llamadas expresiones lambda , [57] que tienen la forma:

[ captura ] ( parámetros ) especificaciones requiere ( opcional ) { cuerpo }          

donde " specs" tiene la forma " en ese orden; cada uno de estos componentes es opcional". Si está ausente, el tipo de retorno se deduce de las declaraciones como si se tratara de una función con el tipo de retorno declarado .specifiers exception attr trailing-return-typereturnauto

Este es un ejemplo de expresión lambda:

[]( int x , int y ) { devolver x + y ; }         

C++11 también admite cierres , aquí llamados capturas. Las capturas se definen entre corchetes [y ]en la declaración de la expresión lambda. El mecanismo permite capturar estas variables por valor o por referencia. La siguiente tabla lo demuestra:

[] // Sin capturas, la lambda se puede convertir de forma implícita en un puntero a función. [ x , & y ] // x se captura por valor y y se captura por referencia. [ & ] // Cualquier variable externa se captura de forma implícita por referencia si se utiliza . [ = ] // Cualquier variable externa se captura de forma implícita por valor si se utiliza. [ & , x ] // x se captura por valor. Las demás variables se capturarán por referencia. [ = , & z ] // z se captura por referencia. Las demás variables se capturarán por valor.         

Las variables capturadas por valor son constantes de forma predeterminada. Si se agregan mutabledespués de la lista de parámetros, se vuelven no constantes.

C++14 y versiones más nuevas admiten init-capture, por ejemplo:

std :: unique_ptr < int > ptr = std :: make_unique < int > ( 42 ); [ ptr ]{ /* ... */ }; // se elimina la asignación de copia para un puntero único [ ptr = std :: move ( ptr )]{ /* ... */ }; // ok           contador automático = [ i = 0 ]() mutable { return i ++ ; }; // se requiere mutable para modificar 'i' contador (); // 0 contador (); // 1 contador (); // 2              

Los siguientes dos ejemplos demuestran el uso de una expresión lambda:

std :: vector < int > some_list { 1 , 2 , 3 , 4 , 5 }; int total = 0 ; std :: for_each ( begin ( some_list ), end ( some_list ), [ & total ]( int x ) { total += x ; }); // Tenga en cuenta que std::accumulate sería una alternativa mucho mejor aquí...                   

Esto calcula el total de todos los elementos de la lista. La variable totalse almacena como parte del cierre de la función lambda. Dado que es una referencia a la variable de pila total, puede cambiar su valor.

std :: vector < int > alguna_lista { 1 , 2 , 3 , 4 , 5 }; int total = 0 ; int valor = 5 ; std :: for_each ( begin ( alguna_lista ), end ( alguna_lista ), [ & total , valor , esto ]( int x ) { total += x * valor * esto -> alguna_función (); });                            

Esto hará totalque se almacene como referencia, pero valuese almacenará como una copia.

La captura de thises especial. Solo se puede capturar por valor, no por referencia. Sin embargo, en C++17 , el objeto actual se puede capturar por valor (denotado por *this), o se puede capturar por referencia (denotado por this). thissolo se puede capturar si la función envolvente más cercana es una función miembro no estática. La lambda tendrá el mismo acceso que el miembro que la creó, en términos de miembros protegidos/privados.

Si thisse captura, ya sea de forma explícita o implícita, también se prueba el alcance de los miembros de la clase incluidos. Para acceder a los miembros de thisno es necesario el uso explícito de this->la sintaxis.

La implementación interna específica puede variar, pero la expectativa es que una función lambda que captura todo por referencia almacene el puntero de pila real de la función en la que se crea, en lugar de referencias individuales a variables de pila. Sin embargo, debido a que la mayoría de las funciones lambda son pequeñas y de alcance local, es probable que sean candidatas para la inserción en línea y, por lo tanto, no necesitan almacenamiento adicional para referencias.

Si se invoca un objeto de cierre que contiene referencias a variables locales después del ámbito de bloque más interno de su creación, el comportamiento no está definido .

Las funciones lambda son objetos de función de un tipo que depende 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 parámetro, el tipo de parámetro debe ser un tipo de plantilla, o debe crear un objeto std::functiono un objeto similar para capturar el valor lambda. El uso de la autopalabra clave puede ayudar a almacenar la función lambda.

auto mi_función_lambda = [ & ]( int x ) { /*...*/ }; auto mi_función_lambda_onheap = nuevo auto ([ = ]( int x ) { /*...*/ });               

A continuación se muestra un ejemplo de cómo almacenar funciones anónimas en variables, vectores y matrices y pasarlas como parámetros con nombre:

#include <funcional> #include <iostream> #include <vector>   doble eval ( std :: función < double ( double ) > f , double x = 2.0 ) { return f ( x ); }         int main () { std :: function < double ( double ) > f0 = []( double x ) { return 1 ; }; auto f1 = []( double x ) { return x ; }; decltype ( f0 ) fa [ 3 ] = { f0 , f1 , []( double x ) { return x * x ; }}; std :: vector < decltype ( f0 ) > fv = { f0 , f1 }; fv . push_back ([]( double x ) { return x * x ; }); for ( size_t i = 0 ; i < fv . size (); i ++ ) { std :: cout << fv [ i ]( 2.0 ) << std :: endl ; } para ( tamaño_t i = 0 ; i < 3 ; i ++ ) { std :: cout << fa [ i ] ( 2.0 ) << std :: endl ; } para ( auto & f : fv ) { std :: cout << f ( 2.0 ) << std :: endl ; } para ( auto & f : fa ) { std :: cout << f ( 2.0 ) << std ::                                                                                                     finl ; } std :: cout << eval ( f0 ) << std :: finl ; std :: cout << eval ( f1 ) << std :: finl ; std :: cout << eval ([]( doble x ) { devolver x * x ; } ) << std :: finl ; }                       

Una expresión lambda con una especificación de captura vacía ( []) se puede convertir implícitamente en un puntero de función con el mismo tipo con el que se declaró la expresión lambda. Por lo tanto, esto es legal:

auto a_lambda_func = []( int x ) -> void { /*...*/ }; void ( * func_ptr )( int ) = a_lambda_func ; func_ptr ( 4 ); //llama a la lambda.              

Desde C++17 , se puede declarar una lambda constexpry, desde C++20 , constevalcon la semántica habitual. Estos especificadores van después de la lista de parámetros, como mutable. A partir de C++23 , la lambda también puede ser staticsi no tiene capturas. No se permite combinar los especificadores staticy .mutable

También desde C++23 una expresión lambda puede ser recursiva a través de explicit thiscomo primer parámetro:

auto fibonacci = []( este auto yo mismo , int n ) { devuelve n <= 1 ? n : yo mismo ( n - 1 ) + yo mismo ( n - 2 ); }; fibonacci ( 7 ); // 13                        

Además de eso, C++23 modificó la sintaxis para que los paréntesis se puedan omitir en el caso de una lambda que no toma argumentos incluso si la lambda tiene un especificador. También hizo que una secuencia de especificadores de atributos que aparezca antes de la lista de parámetros, los especificadores de lambda o el especificador noexcept (debe haber uno de ellos) se aplique al operador de llamada de función o a la plantilla de operador del tipo de cierre. De lo contrario, se aplica al tipo del operador de llamada de función o a la plantilla de operador. Anteriormente, dicha secuencia siempre se aplicaba al tipo del operador de llamada de función o a la plantilla de operador del tipo de cierre, lo que hacía que, por ejemplo, el [[noreturn]]atributo fuera imposible de usar con lambdas.

La biblioteca Boost también proporciona su propia sintaxis para funciones lambda, utilizando la siguiente sintaxis: [58]

para_cada ( a.begin (), a.end ( ) , std :: cout << _1 << ' ' ) ;      

Desde C++14 , los parámetros de función de una lambda se pueden declarar con auto. La lambda resultante se denomina lambda genérica y es esencialmente una plantilla de función anónima, ya que las reglas para la deducción de tipos de los parámetros automáticos son las reglas de deducción de argumentos de plantilla. A partir de C++20 , los parámetros de plantilla también se pueden declarar explícitamente con la siguiente sintaxis:

[ captura ] < tparams > requiere ( opcional ) ( parámetros ) especificaciones requiere ( opcional ) { cuerpo }              

DO#

En C# , el soporte para funciones anónimas se ha profundizado a través de las distintas versiones del compilador del lenguaje. El lenguaje v3.0, lanzado en noviembre de 2007 con .NET Framework v3.5, tiene soporte completo para funciones anónimas. [59] : 7–8  [60] : 26  C# las denomina expresiones lambda , siguiendo la versión original de funciones anónimas, el cálculo lambda . [61] [59] : 7–8, 91  [60] : 91 

// el primer int es el tipo x' // el segundo int es el tipo de retorno // <see href="http://msdn.microsoft.com/en-us/library/bb549151.aspx" />Func<int,int> foo = x => x * x;Console.WriteLine(foo(7));

Si bien la función es anónima, no se puede asignar a una variable tipificada implícitamente, porque la sintaxis lambda se puede usar para denotar una función anónima o un árbol de expresiones, y el compilador no puede decidir automáticamente la elección. [59] : 101–103  Por ejemplo, esto no funciona:

// ¡NO se compilará! var foo = ( int x ) => x * x ;        

Sin embargo, una expresión lambda puede participar en la inferencia de tipos y puede usarse como argumento de un método , por ejemplo, para usar funciones anónimas con la capacidad Map disponible con System.Collections.Generic.List(en el ConvertAll()método):

// Inicializa la lista: var values ​​= new List < int > () { 7 , 13 , 4 , 9 , 3 }; // Asigna la función anónima a todos los elementos de la lista y devuelve la nueva lista var foo = values ​​. ConvertAll ( d => d * d ) ; // El resultado de la variable foo es del tipo System.Collections.Generic.List<Int32>                    

Las versiones anteriores de C# tenían un soporte más limitado para funciones anónimas. C# v1.0, introducido en febrero de 2002 con .NET Framework v1.0, proporcionó soporte parcial para funciones anónimas mediante el uso de delegados . [59] : 6  C# las denomina expresiones lambda , siguiendo la versión original de funciones anónimas, el cálculo lambda . [59] : 91  Esta construcción es algo similar a los delegados de PHP. En C# 1.0, los delegados son como punteros de función que hacen referencia a un método nombrado explícitamente dentro de una clase. (Pero a diferencia de PHP, el nombre no es necesario en el momento en que se usa el delegado). C# v2.0, lanzado en noviembre de 2005 con .NET Framework v2.0, introdujo el concepto de métodos anónimos como una forma de escribir bloques de declaraciones en línea sin nombre que se pueden ejecutar en una invocación de delegado. [59] : 6–7  C# 3.0 continúa admitiendo estas construcciones, pero también admite la construcción de expresión lambda.

Este ejemplo se compilará en C# 3.0 y exhibirá las tres formas:

 public class TestDriver { delegate int SquareDelegate ( int d ); static int Square ( int d ) { return d * d ; } static void Main ( string [ ] args ) { // C# 1.0: Se necesita la sintaxis de delegado original // inicializando con un método nombrado. SquareDelegate A = new SquareDelegate ( Square ); System.Console.WriteLine ( A ( 3 )); // C# 2.0: Se puede inicializar un delegado con // código en línea, llamado "método anónimo". Este // método toma un int como parámetro de entrada. SquareDelegate B = delegate(int d) { return d * d; }; System.Console.WriteLine ( B ( 5 ) ) ; // C # 3.0 . Se puede inicializar un delegado con // una expresión lambda . La lambda toma un int y devuelve un int. // El compilador infiere el tipo de x. SquareDelegate C = x => x * x ; System . Console . WriteLine ( C ( 7 )); // C# 3.0. Un delegado que acepta una entrada y // devuelve una salida también se puede declarar implícitamente con el tipo Func<>. System . Func < int , int > D = x => x * x ; System . Console . WriteLine ( D ( 9 )); } }                                                                           

En el caso de la versión C# 2.0, el compilador de 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 obtiene un nombre generado, por supuesto; este nombre generado se basa en el nombre del método en el que se declara el Delegado. Pero el nombre no se expone al código de la aplicación excepto mediante el uso de la reflexión . [59] : 103  En el caso de la versión C# 3.0, se aplica el mismo mecanismo.

Lenguaje de marcado ColdFusion (CFML)

Usando elfunciónpalabra clave:

fn  =  función (){  // declaraciones };

O usando una función de flecha:

fn  =  ()  =>  {  // declaraciones };fn  =  ()  =>  singleExpression  // singleExpression se devuelve de forma implícita. No es necesario utilizar llaves ni la palabra clave returnfn  =  singleParam  =>  {  // si la función de flecha tiene solo un parámetro, no hay necesidad de paréntesis  // declaraciones }fn  =  ( x ,  y )  =>  {  // si la función de flecha tiene cero o múltiples parámetros, es necesario utilizar paréntesis  // declaraciones }

CFML admite cualquier declaración dentro de la definición de la función, no simplemente expresiones.

CFML admite funciones anónimas recursivas:

factorial  =  función ( n ){  devolver  n  >  1  ?  n  *  factorial ( n - 1 )  :  1 ; };

Las funciones anónimas CFML implementan el cierre.

D

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

return_type delegado ( argumentos ){ /*cuerpo*/ } 

Si no hay ambigüedades, se pueden omitir el tipo de retorno y la palabra clave delegate .

( x ){ return x * x ;} delegate ( x ){ return x * x ;} // si se necesita más verbosidad ( int x ){ return x * x ;} // si no se puede inferir el tipo de parámetro delegate ( int x ){ return x * x ;} // lo mismo delegate double ( int x ){ return x * x ;} // si el tipo de retorno debe forzarse manualmente               

Desde la versión 2.0, D asigna cierres en el montón a menos que el compilador pueda demostrar que no es necesario; la scopepalabra clave se puede utilizar para forzar la asignación en la pila. Desde la versión 2.058, es posible utilizar la notación abreviada:

x => x * x ; ( int x ) => x * x ; ( x , y ) => x * y ; ( int x , int y ) => x * y ;            

Se puede asignar una función anónima a una variable y utilizarla de la siguiente manera:

auto sqr = ( doble x ){ devolver x * x ;}; doble y = sqr ( 4 );        

Dardo

Dart admite funciones anónimas. [12]

var sqr = ( x ) => x * x ; imprimir ( sqr ( 5 ));       

o

imprimir ((( x ) => x * x )( 5 ));    

Delfos

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

demostración del programa ; tipo TSimpleProcedure = referencia al procedimiento ; TSimpleFunction = referencia a la función ( const x : string ) : entero ;             var x1 : TSimpleProcedure ; y1 : TSimpleFunction ;    begin x1 := procedimiento begin Writeln ( 'Hola Mundo' ) ; end ; x1 ; //invocar el método anónimo recién definido         y1 := function ( const x : string ) : Entero begin Resultado := Longitud ( x ) ; end ; Writeln ( y1 ( 'bar' )) ; end .            

PascalABC.NET

PascalABC.NET admite funciones anónimas que utilizan la sintaxis lambda

comienza var n := 10000000 ; var pp := ( 1 .. n ) . Selecciona ( x -> ( Aleatorio , Aleatorio )) . Donde ( p -> Sqr ( p [ 0 ]) + Sqr ( p [ 1 ]) < 1 ) . Conde / n * 4 ; Imprimir ( pp ) ; fin .                         

Elixir

Elixir utiliza el cierre fn para funciones anónimas. [16]

suma = fn ( a , b ) -> a + b fin suma . ( 4 , 3 ) #=> 7         cuadrado = fn ( x ) -> x * x fin de enumeración . map [ 1 , 2 , 3 , 4 ], cuadrado #=> [1, 4, 9, 16]            

Erlang

Erlang utiliza una sintaxis para funciones anónimas similar a la de las funciones con nombre. [17]

% Función anónima ligada a la variable Cuadrado Cuadrado = fun ( X ) -> X * X fin .       % Función nombrada con la misma funcionalidad cuadrado ( X ) -> X * X .    

Ir

Go admite funciones anónimas. [22]

foo := func(x int) int {return x * x}fmt.Println(foo(10))

Haskell

Haskell uses a concise syntax for anonymous functions (lambda expressions). The backslash is supposed to resemble λ.

\x -> x * x

Lambda expressions are fully integrated with the type inference engine, and support all the syntax and features of "ordinary" functions (except for the use of multiple definitions for pattern-matching, since the argument list is only specified once).

map (\x -> x * x) [1..5] -- returns [1, 4, 9, 16, 25]

The following are all equivalent:

f x y = x + yf x = \y -> x + yf = \x y -> x + y

Haxe

In Haxe, anonymous functions are called lambda, and use the syntax function(argument-list) expression; .

var f = function(x) return x*x;f(8); // 64(function(x,y) return x+y)(5,6); // 11

Java

Java supports anonymous functions, named Lambda Expressions, starting with JDK 8.[62]

A lambda expression consists of a comma separated list of the formal parameters enclosed in parentheses, an arrow token (->), and a body. Data types of the parameters can always be omitted, as can the parentheses if there is only one parameter. The body can consist of one statement or a statement block.[63]

// with no parameter() -> System.out.println("Hello, world.")// with one parameter (this example is an identity function).a -> a// with one expression(a, b) -> a + b// with explicit type information(long id, String name) -> "id: " + id + ", name:" + name// with a code block(a, b) -> { return a + b; }// with multiple statements in the lambda body. It needs a code block.// This example also includes two nested lambda expressions (the first one is also a closure).(id, defaultPrice) -> { Optional<Product> product = productList.stream().filter(p -> p.getId() == id).findFirst(); return product.map(p -> p.getPrice()).orElse(defaultPrice);}

Lambda expressions are converted to "functional interfaces" (defined as interfaces that contain only one abstract method in addition to one or more default or static methods),[63] as in the following example:

public class Calculator { interface IntegerMath { int operation(int a, int b); default IntegerMath swap() { return (a, b) -> operation(b, a); } } private static int apply(int a, int b, IntegerMath op) { return op.operation(a, b); } public static void main(String... args) { IntegerMath addition = (a, b) -> a + b; IntegerMath subtraction = (a, b) -> a - b; System.out.println("40 + 2 = " + apply(40, 2, addition)); System.out.println("20 - 10 = " + apply(20, 10, subtraction)); System.out.println("10 - 20 = " + apply(20, 10, subtraction.swap()));  }}

In this example, a functional interface called IntegerMath is declared. Lambda expressions that implement IntegerMath are passed to the apply() method to be executed. Default methods like swap define methods on functions.

Java 8 introduced another mechanism named method reference (the :: operator) to create a lambda on an existing method. A method reference does not indicate the number or types of arguments because those are extracted from the abstract method of the functional interface.

IntBinaryOperator sum = Integer::sum;

In the example above, the functional interface IntBinaryOperator declares an abstract method int applyAsInt(int, int), so the compiler looks for a method int sum(int, int) in the class java.lang.Integer.

Differences compared to Anonymous Classes

Anonymous classes of lambda-compatible interfaces are similar, but not exactly equivalent, to lambda expressions. To illustrate, in the following example, anonymousClass and lambdaExpression are both instances of IntegerMath that add their two parameters:

IntegerMath anonymousClass = new IntegerMath() { @Override public int operation(int a, int b) { return a + b; }};IntegerMath lambdaExpression = (a, b) -> a + b;

The main difference here is that the lambda expression does not necessarily need to allocate a new instance for the IntegerMath, and can return the same instance every time this code is run.[64]Additionally, in the OpenJDK implementation at least, lambdas are compiled to invokedynamic instructions, with the lambda body inserted as a static method into the surrounding class,[65] rather than generating a new class file entirely.

Java limitations

Java 8 lambdas have the following limitations:

JavaScript

JavaScript/ECMAScript supports anonymous functions.

alert((function(x){ return x * x;})(10));

ES6 supports "arrow function" syntax, where a => symbol separates the anonymous function's parameter list from the body:

alert((x => x * x)(10));

This construct is often used in Bookmarklets. For example, to change the title of the current document (visible in its window's title bar) to its URL, the following bookmarklet may seem to work.

document.title=location.href;

However, as the assignment statement returns a value (the URL itself), many browsers actually create a new page to display this value.

Instead, an anonymous function, that does not return a value, can be used:

(function(){document.title=location.href;})();

The function statement in the first (outer) pair of parentheses declares an anonymous function, which is then executed when used with the last pair of parentheses. This is almost equivalent to the following, which populates the environment with f unlike an anonymous function.

var f = function(){document.title=location.href;}; f();

Use void() to avoid new pages for arbitrary anonymous functions:

void(function(){return document.title=location.href;}());

or just:

void(document.title=location.href);

JavaScript has syntactic subtleties for the semantics of defining, invoking and evaluating anonymous functions. These subliminal nuances are a direct consequence of the evaluation of parenthetical expressions. The following constructs which are called immediately-invoked function expression illustrate this:

(function(){ ... }())

and

(function(){ ... })()

Representing "function(){ ... }" by f, the form of the constructs are a parenthetical within a parenthetical (f()) and a parenthetical applied to a parenthetical (f)().

Note the general syntactic ambiguity of a parenthetical expression, parenthesized arguments to a function and the parentheses around the formal parameters in a function definition. In particular, JavaScript defines a , (comma) operator in the context of a parenthetical expression. It is no mere coincidence that the syntactic forms coincide for an expression and a function's arguments (ignoring the function formal parameter syntax)! If f is not identified in the constructs above, they become (()) and ()(). The first provides no syntactic hint of any resident function but the second MUST evaluate the first parenthetical as a function to be legal JavaScript. (Aside: for instance, the ()'s could be ([],{},42,"abc",function(){}) as long as the expression evaluates to a function.)

Also, a function is an Object instance (likewise objects are Function instances) and the object literal notation brackets, {} for braced code, are used when defining a function this way (as opposed to using new Function(...)). In a very broad non-rigorous sense (especially since global bindings are compromised), an arbitrary sequence of braced JavaScript statements, {stuff}, can be considered to be a fixed point of

(function(){( function(){( ... {( function(){stuff}() )} ... )}() )}() )

More correctly but with caveats,

( function(){stuff}() ) ~= A_Fixed_Point_of( function(){ return function(){ return ... { return function(){stuff}() } ... }() }() )

Note the implications of the anonymous function in the JavaScript fragments that follow:

Performance metrics to analyze the space and time complexities of function calls, call stack, etc. in a JavaScript interpreter engine implement easily with these last anonymous function constructs. From the implications of the results, it is possible to deduce some of an engine's recursive versus iterative implementation details, especially tail-recursion.

Julia

In Julia anonymous functions are defined using the syntax (arguments)->(expression),

julia> f = x -> x*x; f(8)64julia> ((x,y)->x+y)(5,6)11

Kotlin

Kotlin supports anonymous functions with the syntax {arguments -> expression},

val sum = { x: Int, y: Int -> x + y }sum(5,6) // returns 11val even = { x: Int -> x%2==0}even(4) // returns true

Lisp

Lisp and Scheme support anonymous functions using the "lambda" construct, which is a reference to lambda calculus. Clojure supports anonymous functions with the "fn" special form and #() reader syntax.

(lambda (arg) (* arg arg))

Common Lisp

Common Lisp has the concept of lambda expressions. A lambda expression is written as a list with the symbol "lambda" as its first element. The list then contains the argument list, documentation or declarations and a function body. Lambda expressions can be used inside lambda forms and with the special operator "function".

(function (lambda (arg) (do-something arg)))

"function" can be abbreviated as #'. Also, macro lambda exists, which expands into a function form:

; using sharp quote#'(lambda (arg) (do-something arg)); using the lambda macro:(lambda (arg) (do-something arg))

One typical use of anonymous functions in Common Lisp is to pass them to higher-order functions like mapcar, which applies a function to each element of a list and returns a list of the results.

(mapcar #'(lambda (x) (* x x)) '(1 2 3 4)); -> (1 4 9 16)

The lambda form in Common Lisp allows a lambda expression to be written in a function call:

((lambda (x y) (+ (sqrt x) (sqrt y))) 10.0 12.0)

Anonymous functions in Common Lisp can also later be given global names:

(setf (symbol-function 'sqr) (lambda (x) (* x x))); which allows us to call it using the name SQR:(sqr 10.0)

Scheme

Scheme's named functions is simply syntactic sugar for anonymous functions bound to names:

(define (somename arg) (do-something arg))

expands (and is equivalent) to

(define somename (lambda (arg) (do-something arg)))

Clojure

Clojure supports anonymous functions through the "fn" special form:

(fn [x] (+ x 3))

There is also a reader syntax to define a lambda:

#(+ % %2%3) ; Defines an anonymous function that takes three arguments and sums them.

Like Scheme, Clojure's "named functions" are simply syntactic sugar for lambdas bound to names:

(defn func [arg] (+ 3 arg))

expands to:

(def func (fn [arg] (+ 3 arg)))

Lua

In Lua (much as in Scheme) all functions are anonymous. A named function in Lua is simply a variable holding a reference to a function object.[66]

Thus, in Lua

function foo(x) return 2*x end

is just syntactical sugar for

foo = function(x) return 2*x end

An example of using anonymous functions for reverse-order sorting:

table.sort(network, function(a,b) return a.name > b.nameend)

Wolfram Language, Mathematica

The Wolfram Language is the programming language of Mathematica. Anonymous functions are important in programming the latter. There are several ways to create them. Below are a few anonymous functions that increment a number. The first is the most common. #1 refers to the first argument and & marks the end of the anonymous function.

 #1+1& Function[x,x+1] x \[Function] x+1

So, for instance:

 f:= #1^2&;f[8] 64 #1+#2&[5,6] 11

Also, Mathematica has an added construct to make recursive anonymous functions. The symbol '#0' refers to the entire function. The following function calculates the factorial of its input:

 If[#1 == 1, 1, #1 * #0[#1-1]]&

For example, 6 factorial would be:

 If[#1 == 1, 1, #1 * #0[#1-1]]&[6]720

MATLAB, Octave

Anonymous functions in MATLAB or Octave are defined using the syntax @(argument-list)expression. Any variables that are not found in the argument list are inherited from the enclosing scope and are captured by value.

>> f = @(x)x*x; f(8)ans = 64>> (@(x,y)x+y)(5,6) % Only works in Octaveans = 11

Maxima

In Maxima anonymous functions are defined using the syntax lambda(argument-list,expression),

f: lambda([x],x*x); f(8);64lambda([x,y],x+y)(5,6);11

ML

The various dialects of ML support anonymous functions.

OCaml

Anonymous functions in OCaml are functions without a declared name. Here is an example of an anonymous function that multiplies its input by two:

fun x -> x*2

In the example, fun is a keyword indicating that the function is an anonymous function. We are passing in an argument x and -> to separate the argument from the body.[67]

F#

F# supports anonymous functions,[18] as follows:

(fun x -> x * x) 20 // 400

Standard ML

Standard ML supports anonymous functions, as follows:

fn arg => arg * arg

Nim

Nim supports multi-line multi-expression anonymous functions. [34]

var anon = proc (var1, var2: int): int = var1 + var2assert anon(1, 2) == 3

Multi-line example:

var anon = func (x: int): bool = if x > 0: result = true else:  result = falseassert anon(9)

Anonymous functions may be passed as input parameters of other functions:

var cities = @["Frankfurt", "Tokyo", "New York"]cities.sort( proc (x, y: string): int = cmp(x.len, y.len))

An anonymous function is basically a function without a name.

Perl

Perl 5

Perl 5 supports anonymous functions,[38] as follows:

(sub { print "I got called\n" })->(); # 1. fully anonymous, called as createdmy $squarer = sub { my $x = shift; $x * $x }; # 2. assigned to a variablesub curry { my ($sub, @args) = @_; return sub { $sub->(@args, @_) }; # 3. as a return value of another function}# example of currying in Perl programmingsub sum { my $tot = 0; $tot += $_ for @_; $tot } # returns the sum of its argumentsmy $curried = curry \&sum, 5, 7, 9;print $curried->(1,2,3), "\n"; # prints 27 ( = 5 + 7 + 9 + 1 + 2 + 3 )

Other constructs take bare blocks as arguments, which serve a function similar to lambda functions of one parameter, but do not have the same parameter-passing convention as functions -- @_ is not set.

my @squares = map { $_ * $_ } 1..10; # map and grep don't use the 'sub' keywordmy @square2 = map $_ * $_, 1..10; # braces unneeded for one expressionmy @bad_example = map { print for @_ } 1..10; # values not passed like normal Perl function

PHP

Before 4.0.1, PHP had no anonymous function support.[68]

PHP 4.0.1 to 5.3

PHP 4.0.1 introduced the create_function which was the initial anonymous function support. This function call makes a new randomly named function and returns its name (as a string)

$foo = create_function('$x', 'return $x*$x;');$bar = create_function("\$x", "return \$x*\$x;");echo $foo(10);

The argument list and function body must be in single quotes, or the dollar signs must be escaped. Otherwise, PHP assumes "$x" means the variable $x and will substitute it into the string (despite possibly not existing) instead of leaving "$x" in the string. For functions with quotes or functions with many variables, it can get quite tedious to ensure the intended function body is what PHP interprets.

Each invocation of create_function makes a new function, which exists for the rest of the program, and cannot be garbage collected, using memory in the program irreversibly. If this is used to create anonymous functions many times, e.g., in a loop, it can cause problems such as memory bloat.

PHP 5.3

PHP 5.3 added a new class called Closure and magic method __invoke() that makes a class instance invocable.[69]

$x = 3;$func = function($z) { return $z * 2; };echo $func($x); // prints 6

In this example, $func is an instance of Closure and echo $func($x) is equivalent to echo $func->__invoke($x). PHP 5.3 mimics anonymous functions but it does not support true anonymous functions because PHP functions are still not first-class objects.

PHP 5.3 does support closures but the variables must be explicitly indicated as such:

$x = 3;$func = function() use(&$x) { $x *= 2; };$func();echo $x; // prints 6

The variable $x is bound by reference so the invocation of $func modifies it and the changes are visible outside of the function.

PHP 7.4

Arrow functions were introduced in PHP 7.4

$x = 3;$func = fn($z) => $z * 2;echo $func($x); // prints 6

Prolog's dialects

Logtalk

Logtalk uses the following syntax for anonymous predicates (lambda expressions):

{FreeVar1, FreeVar2, ...}/[LambdaParameter1, LambdaParameter2, ...]>>Goal

A simple example with no free variables and using a list mapping predicate is:

| ?- meta::map([X,Y]>>(Y is 2*X), [1,2,3], Ys).Ys = [2,4,6]yes

Currying is also supported. The above example can be written as:

| ?- meta::map([X]>>([Y]>>(Y is 2*X)), [1,2,3], Ys).Ys = [2,4,6]yes

Visual Prolog

Anonymous functions (in general anonymous predicates) were introduced in Visual Prolog in version 7.2.[70] Anonymous predicates can capture values from the context. If created in an object member, it can also access the object state (by capturing This).

mkAdder returns an anonymous function, which has captured the argument X in the closure. The returned function is a function that adds X to its argument:

clauses mkAdder(X) = { (Y) = X+Y }.

Python

Python supports simple anonymous functions through the lambda form.[40] The executable body of the lambda must be an expression and can't be a statement, which is a restriction that limits its utility. The value returned by the lambda is the value of the contained expression. Lambda forms can be used anywhere ordinary functions can. However these restrictions make it a very limited version of a normal function. Here is an example:

>>> foo = lambda x: x * x>>> foo(10)100

In general, the Python convention encourages the use of named functions defined in the same scope as one might typically use an anonymous function in other languages. This is acceptable as locally defined functions implement the full power of closures and are almost as efficient as the use of a lambda in Python. In this example, the built-in power function can be said to have been curried:

>>> def make_pow(n):...  def fixed_exponent_pow(x):...  return pow(x, n)...  return fixed_exponent_pow...>>> sqr = make_pow(2)>>> sqr(10)100>>> cub = make_pow(3)>>> cub(10)1000

R

In R the anonymous functions are defined using the syntax function(argument-list)expression , which has shorthand since version 4.1.0 \, akin to Haskell.

> f <- function(x)x*x; f(8)[1] 64> (function(x,y)x+y)(5,6)[1] 11> # Since R 4.1.0> (\(x,y) x+y)(5, 6)[1] 11

Raku

In Raku, all blocks (even those associated with if, while, etc.) are anonymous functions. A block that is not used as an rvalue is executed immediately.

  1. fully anonymous, called as created
    { say "I got called" };
  2. assigned to a variable
    my $squarer1 = -> $x { $x * $x }; # 2a. pointy blockmy $squarer2 = { $^x * $^x }; # 2b. twigilmy $squarer3 = { my $x = shift @_; $x * $x }; # 2c. Perl 5 style
  3. currying
    sub add ($m, $n) { $m + $n }my $seven = add(3, 4);my $add_one = &add.assuming(m => 1);my $eight = $add_one($seven);
  4. WhateverCode object
    my $w = * - 1; # WhateverCode objectmy $b = { $_ - 1 }; # same functionality, but as Callable block

Ruby

Ruby supports anonymous functions by using a syntactical structure called block. There are two data types for blocks in Ruby. Procs behave similarly to closures, whereas lambdas behave more analogous to an anonymous function.[43] When passed to a method, a block is converted into a Proc in some circumstances.

# Example 1:# Purely anonymous functions using blocks.ex = [16.2, 24.1, 48.3, 32.4, 8.5]=> [16.2, 24.1, 48.3, 32.4, 8.5]ex.sort_by { |x| x - x.to_i } # Sort by fractional part, ignoring integer part.=> [24.1, 16.2, 48.3, 32.4, 8.5]# Example 2:# First-class functions as an explicit object of Proc -ex = Proc.new { puts "Hello, world!" }=> #<Proc:0x007ff4598705a0@(irb):7>ex.callHello, world!=> nil# Example 3:# Function that returns lambda function object with parametersdef multiple_of?(n) lambda{|x| x % n == 0}end=> nilmultiple_four = multiple_of?(4)=> #<Proc:0x007ff458b45f88@(irb):12 (lambda)>multiple_four.call(16)=> truemultiple_four[15]=> false

Rust

In Rust, anonymous functions are called closures.[71] They are defined using the following syntax:

|<parameter-name>: <type>| -> <return-type> { <body> };

For example:

let f = |x: i32| -> i32 { x * 2 };

With type inference, however, the compiler is able to infer the type of each parameter and the return type, so the above form can be written as:

let f = |x| { x * 2 };

With closures with a single expression (i.e. a body with one line) and implicit return type, the curly braces may be omitted:

let f = |x| x * 2;

Closures with no input parameter are written like so:

let f = || println!("Hello, world!");

Closures may be passed as input parameters of functions that expect a function pointer:

// A function which takes a function pointer as an argument and calls it with// the value `5`.fn apply(f: fn(i32) -> i32) -> i32 { // No semicolon, to indicate an implicit return f(5)}fn main() { // Defining the closure let f = |x| x * 2; println!("{}", apply(f)); // 10 println!("{}", f(5)); // 10}

However, one may need complex rules to describe how values in the body of the closure are captured. They are implemented using the Fn, FnMut, and FnOnce traits:[72]

With these traits, the compiler will capture variables in the least restrictive manner possible.[72] They help govern how values are moved around between scopes, which is largely important since Rust follows a lifetime construct to ensure values are "borrowed" and moved in a predictable and explicit manner.[73]

The following demonstrates how one may pass a closure as an input parameter using the Fn trait:

// A function that takes a value of type F (which is defined as// a generic type that implements the `Fn` trait, e.g. a closure)// and calls it with the value `5`.fn apply_by_ref<F>(f: F) -> i32 where F: Fn(i32) -> i32{ f(5)}fn main() { let f = |x| { println!("I got the value: {}", x); x * 2 };  // Applies the function before printing its return value println!("5 * 2 = {}", apply_by_ref(f));}// ~~ Program output ~~// I got the value: 5// 5 * 2 = 10

The previous function definition can also be shortened for convenience as follows:

fn apply_by_ref(f: impl Fn(i32) -> i32) -> i32 { f(5)}

Scala

In Scala, anonymous functions use the following syntax:[74]

(x: Int, y: Int) => x + y

In certain contexts, like when an anonymous function is a parameter being passed to another function, the compiler can infer the types of the parameters of the anonymous function and they can be omitted in the syntax. In such contexts, it is also possible to use a shorthand for anonymous functions using the underscore character to introduce unnamed parameters.

val list = List(1, 2, 3, 4)list.reduceLeft( (x, y) => x + y ) // Here, the compiler can infer that the types of x and y are both Int. // Thus, it needs no type annotations on the parameters of the anonymous function.list.reduceLeft( _ + _ ) // Each underscore stands for a new unnamed parameter in the anonymous function. // This results in an even shorter equivalent to the anonymous function above.

Smalltalk

In Smalltalk anonymous functions are called blocks and they are invoked (called) by sending them a "value" message. If several arguments are to be passed, a "value:...value:" message with a corresponding number of value arguments must be used.

For example, in GNU Smalltalk,

st> f:=[:x|x*x]. f value: 8 .64st> [:x :y|x+y] value: 5 value: 6 .11

Smalltalk blocks are technically closures, allowing them to outlive their defining scope and still refer to the variables declared therein.

st> f := [:a|[:n|a+n]] value: 100 .a BlockClosure"returns the inner block, which adds 100 (captured in "a" variable) to its argument."st> f value: 1 .101st> f value: 2 .102

Swift

In Swift, anonymous functions are called closures.[47] The syntax has following form:

{ (parameters) -> returnType in statement}

For example:

{ (s1: String, s2: String) -> Bool in return s1 > s2}

For sake of brevity and expressiveness, the parameter types and return type can be omitted if these can be inferred:

{ s1, s2 in return s1 > s2 }

Similarly, Swift also supports implicit return statements for one-statement closures:

{ s1, s2 in s1 > s2 }

Finally, the parameter names can be omitted as well; when omitted, the parameters are referenced using shorthand argument names, consisting of the $ symbol followed by their position (e.g. $0, $1, $2, etc.):

{ $0 > $1 }

Tcl

In Tcl, applying the anonymous squaring function to 2 looks as follows:[75]

apply {x {expr {$x*$x}}} 2# returns 4

This example involves two candidates for what it means to be a function in Tcl. The most generic is usually called a command prefix, and if the variable f holds such a function, then the way to perform the function application f(x) would be

{*}$f $x

where {*} is the expansion prefix (new in Tcl 8.5). The command prefix in the above example is apply {x {expr {$x*$x}}} Command names can be bound to command prefixes by means of the interp alias command. Command prefixes support currying. Command prefixes are very common in Tcl APIs.

The other candidate for "function" in Tcl is usually called a lambda, and appears as the {x {expr {$x*$x}}} part of the above example. This is the part which caches the compiled form of the anonymous function, but it can only be invoked by being passed to the apply command. Lambdas do not support currying, unless paired with an apply to form a command prefix. Lambdas are rare in Tcl APIs.

Vala

In Vala, anonymous functions are supported as lambda expressions.[76]

delegate int IntOp (int x, int y);void main () {IntOp foo = (x, y) => x * y;stdout.printf("%d\n", foo(10,5));}

Visual Basic .NET

Visual Basic .NET 2008 introduced anonymous functions through the lambda form. Combined with implicit typing, VB provides an economical syntax for anonymous functions. As with Python, in VB.NET, anonymous functions must be defined on one line; they cannot be compound statements. Further, an anonymous function in VB.NET must truly be a VB.NET Function - it must return a value.

Dim foo = Function(x) x * xConsole.WriteLine(foo(10))

Visual Basic.NET 2010 added support for multiline lambda expressions and anonymous functions without a return value. For example, a function for use in a Thread.

Dim t As New System.Threading.Thread(Sub () For n As Integer = 0 To 10 'Count to 10 Console.WriteLine(n) 'Print each number Next End Sub )t.Start()

See also

References

  1. ^ "Higher order functions". learnyouahaskell.com. Retrieved 3 December 2014.
  2. ^ Fernandez, Maribel (2009), Models of Computation: An Introduction to Computability Theory, Undergraduate Topics in Computer Science, Springer Science & Business Media, p. 33, ISBN 9781848824348, The Lambda calculus ... was introduced by Alonzo Church in the 1930s as a precise notation for a theory of anonymous functions
  3. ^ "Arrow function expressions - JavaScript". MDN. Retrieved August 21, 2019.
  4. ^ "Access Types". www.adaic.org. Retrieved 2024-06-27.
  5. ^ "Bash lambda". GitHub. 2019-03-08.
  6. ^ BillWagner. "Lambda expressions - C# reference". docs.microsoft.com. Retrieved 2020-11-24.
  7. ^ "Closure support". Archived from the original on 2014-01-06. Retrieved 2014-01-05.
  8. ^ "Whats new in ColdFusion 10". Archived from the original on 2014-01-06. Retrieved 2014-01-05.
  9. ^ "Clojure - Higher Order Functions". clojure.org. Retrieved 2022-01-14.
  10. ^ "Managed COBOL Reference". Micro Focus Documentation. Micro Focus. Archived from the original on 25 February 2014. Retrieved 25 February 2014.
  11. ^ "Functions - D Programming Language". dlang.org. Retrieved 2022-01-14.
  12. ^ a b "A tour of the Dart language". dart.dev. Retrieved 2020-11-24.
  13. ^ "Anonymous Methods in Delphi - RAD Studio". docwiki.embarcadero.com. Retrieved 2020-11-24.
  14. ^ "Functions — Dylan Programming". opendylan.org. Retrieved 2022-01-14.
  15. ^ "docs/syntax". elm-lang.org. Retrieved 2022-01-14.
  16. ^ a b "Erlang/Elixir Syntax: A Crash Course". elixir-lang.github.com. Retrieved 2020-11-24.
  17. ^ a b "Erlang -- Funs". erlang.org. Retrieved 2020-11-24.
  18. ^ a b cartermp. "Lambda Expressions: The fun Keyword - F#". docs.microsoft.com. Retrieved 2020-11-24.
  19. ^ "LAMBDA: The ultimate Excel worksheet function". microsoft.com. 25 January 2021. Retrieved 2021-03-30.
  20. ^ "Quotations - Factor Documentation". Retrieved 26 December 2015. A quotation is an anonymous function (a value denoting a snippet of code) which can be used as a value and called using the Fundamental combinators.
  21. ^ "Frink". frinklang.org. Retrieved 2020-11-24.
  22. ^ a b "Anonymous Functions in GoLang". GoLang Docs. 9 January 2020. Retrieved 2020-11-24.
  23. ^ "Gosu Documentation" (PDF). Retrieved 4 March 2013.
  24. ^ "Groovy Documentation". Archived from the original on 22 May 2012. Retrieved 29 May 2012.
  25. ^ "Anonymous function - HaskellWiki". wiki.haskell.org. Retrieved 2022-01-14.
  26. ^ "Lambda". Haxe - The Cross-platform Toolkit. Retrieved 2022-01-14.
  27. ^ "Functions - JavaScript | MDN". developer.mozilla.org. Retrieved 2022-01-14.
  28. ^ "Functions · The Julia Language". docs.julialang.org. Retrieved 2020-11-24.
  29. ^ "Higher-Order Functions and Lambdas - Kotlin Programming Language". Kotlin. Retrieved 2020-11-24.
  30. ^ "Programming in Lua : 6". www.lua.org. Retrieved 2020-11-24.
  31. ^ "Maple Programming: 1.6: Anonymous functions and expressions - Application Center". www.maplesoft.com. Retrieved 2020-11-24.
  32. ^ "Anonymous Functions - MATLAB & Simulink". www.mathworks.com. Retrieved 2022-01-14.
  33. ^ "Maxima 5.17.1 Manual: 39. Function Definition". maths.cnam.fr. Retrieved 2020-11-24.
  34. ^ a b "Nim Manual". nim-lang.github.io.
  35. ^ "Code Examples – OCaml". ocaml.org. Retrieved 2020-11-24.
  36. ^ "GNU Octave: Anonymous Functions". octave.org. Retrieved 2020-11-24.
  37. ^ "Function Literals". OpenSCAD User Manual. Wikibooks. Retrieved 22 February 2021.
  38. ^ a b "perlsub - Perl subroutines - Perldoc Browser". perldoc.perl.org. Retrieved 2020-11-24.
  39. ^ "PHP: Anonymous functions - Manual". www.php.net. Retrieved 2020-11-24.
  40. ^ a b "6. Expressions — Python 3.9.0 documentation". docs.python.org. Retrieved 2020-11-24.
  41. ^ "4.4 Functions: lambda". docs.racket-lang.org. Retrieved 2020-11-24.
  42. ^ "Functions". docs.raku.org. Retrieved 2022-01-14.
  43. ^ a b Sosinski, Robert (2008-12-21). "Understanding Ruby Blocks, Procs and Lambdas". Reactive.IO. Archived from the original on 2014-05-31. Retrieved 2014-05-30.
  44. ^ "Closures: Anonymous Functions that Can Capture Their Environment - The Rust Programming Language". doc.rust-lang.org. Retrieved 2022-01-14.
  45. ^ "Anonymous Functions". Scala Documentation. Retrieved 2022-01-14.
  46. ^ "Recitation 3: Higher order functions". www.cs.cornell.edu. Retrieved 2022-01-14.
  47. ^ a b "Closures — The Swift Programming Language (Swift 5.5)". docs.swift.org.
  48. ^ "Documentation - Everyday Types". www.typescriptlang.org. Retrieved 2022-01-14.
  49. ^ "Function Type - Typst Documentation". typst.app. Retrieved 2024-09-10.
  50. ^ a b "Projects/Vala/Tutorial - GNOME Wiki!". wiki.gnome.org. Retrieved 2020-11-24.
  51. ^ KathleenDollard (15 September 2021). "Lambda Expressions - Visual Basic". docs.microsoft.com. Retrieved 2022-01-14.
  52. ^ "Language Reference/Terms/Anonymous Predicates - wiki.visual-prolog.com". wiki.visual-prolog.com. Retrieved 2022-01-14.
  53. ^ "Pure Anonymous Function: Elementary Introduction to the Wolfram Language". www.wolfram.com. Retrieved 2022-01-14.
  54. ^ "Lambdas, Closures and everything in between · Issue #1048 · ziglang/zig". GitHub. Retrieved 2023-08-21.
  55. ^ "Expresiones de declaración (utilizando la colección de compiladores GNU (GCC))". gcc.gnu.org . Consultado el 12 de enero de 2022 .
  56. ^ "Especificación del lenguaje para bloques — Documentación de Clang 13". clang.llvm.org . Consultado el 14 de enero de 2022 .
  57. ^ "Expresiones Lambda (desde C++11) - cppreference.com". es.cppreference.com . Consultado el 14 de enero de 2022 .
  58. ^ Järvi, Jaakko; Powell, Gary (nd). "Capítulo 16. Boost.Lambda". Documentación de Boost . Boost . Consultado el 22 de diciembre de 2014 .
  59. ^ abcdefg Skeet, Jon (23 de marzo de 2019). C# en profundidad . Manning. ISBN 978-1617294532.
  60. ^ ab Albahari, José (2022). C# 10 en pocas palabras . O'Reilly. ISBN 978-1-098-12195-2.
  61. ^ "Especificación del lenguaje C# 5.0". Centro de descargas de Microsoft .
  62. ^ "Novedades en JDK 8".
  63. ^ ab Los tutoriales de Java: expresiones Lambda, docs.oracle.com
  64. ^ "Capítulo 15. Expresiones". docs.oracle.com .
  65. ^ "jdk/LambdaMethod.java". GitHub .
  66. ^ "Programación en Lua - Más sobre funciones". Archivado desde el original el 14 de mayo de 2008. Consultado el 25 de abril de 2008 .
  67. ^ "2.7. Funciones anónimas · GitBook". www.cs.cornell.edu .
  68. ^ http://php.net/create_function la parte superior de la página lo indica con "(PHP 4 >= 4.0.1, PHP 5)"
  69. ^ "PHP: rfc:cierres". wiki.php.net .
  70. ^ "Predicados anónimos".en Referencia del lenguaje Visual Prolog
  71. ^ "Cierres - Rust por ejemplo". doc.rust-lang.org .
  72. ^ ab "Como parámetros de entrada - Rust por ejemplo". doc.rust-lang.org .
  73. ^ "Vidas - Rust con el ejemplo". doc.rust-lang.org .
  74. ^ "Sintaxis de funciones anónimas - Documentación de Scala". Archivado desde el original el 23 de julio de 2013. Consultado el 31 de diciembre de 2010 .
  75. ^ aplicar página del manual, recuperada el 6 de septiembre de 2012.
  76. ^ Manual de referencia de Vala, consultado el 9 de junio de 2021.

Enlaces externos