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.
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 ", x ↦ M . Compárese con la sintaxis de JavaScript de . [3]x => M
Las funciones anónimas se pueden utilizar para contener funcionalidades que no necesitan nombrarse y posiblemente para usos 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.
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.2
tiene el nombre de clase " float
", 10
tiene el nombre de clase " int
" y 'number'
tiene el nombre de clase " str
". El orden de clasificación es " float
", " int
" y luego " str
".
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.
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
.
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.
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 ]
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 ]
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" reduce
en 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.
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.
This list is incomplete; you can help by adding missing items. (August 2008) |
Idioma | Apoyo | Notas |
---|---|---|
Script de acción | Y | |
Ada | Y | Las funciones de expresión son parte de Ada2012, acceso a subprograma [4] |
ALGOL 68 | Y | |
APL | Y | Las APL de Dyalog, ngn y dzaima son totalmente compatibles con dfns y funciones tácitas. La APL de GNU tiene un soporte bastante limitado para dfns. |
Lenguajes ensambladores | N | |
AHK | Y | Desde AutoHotkey V2 se admiten funciones anónimas con una sintaxis similar a JavaScript. |
Intento | Y | Se ha creado una biblioteca para soportar funciones anónimas en Bash. [5] |
do | N | Se proporciona soporte en Clang y junto con la biblioteca rt del compilador LLVM . Se proporciona soporte para GCC para una implementación de macro que permite la posibilidad de uso. Vea a continuación para obtener más detalles. |
DO# | Y | [6] |
C++ | Y | A partir del estándar C++11 |
LCM | Y | A partir de Railo 4, [7] ColdFusion 10 [8] |
Clojure | Y | [9] |
COBOL | N | El dialecto COBOL administrado no estándar de Micro Focus admite lambdas, que se denominan delegados/métodos anónimos. [10] |
Rizo | Y | |
D | Y | [11] |
Dardo | Y | [12] |
Delfos | Y | [13] |
Dylan | Y | [14] |
Torre Eiffel | Y | |
Olmo | Y | [15] |
Elixir | Y | [16] |
Erlang | Y | [17] |
F# | Y | [18] |
Sobresalir | Y | Función de hoja de cálculo de Excel, versión beta de 2021 [19] |
Factor | Y | Las "citas" respaldan esto [20] |
Fortran | N | |
friki | Y | [21] |
Ir | Y | [22] |
Gosu | Y | [23] |
Genial | Y | [24] |
Haskell | Y | [25] |
Hacha | Y | [26] |
Java | Y | Compatible con Java 8. Consulta la sección de limitaciones de Java a continuación para obtener más detalles. |
JavaScript | Y | [27] |
Julia | Y | [28] |
Kotlin | Y | [29] |
Ceceo | Y | |
Charla de registro | Y | |
Lua | Y | [30] |
PAPERAS | N | |
Arce | Y | [31] |
MATLAB | Y | [32] |
Máxima | Y | [33] |
Nim | Y | [34] |
OCaml | Y | [35] |
Octava | Y | [36] |
Objeto Pascal | Y | Delphi, un dialecto de Object Pascal, admite funciones anónimas (formalmente, métodos anónimos ) de forma nativa desde Delphi 2009. El dialecto Oxygene Object Pascal también las admite. |
Objetivo-C (Mac OS X 10.6+) | Y | Llamados bloques ; además de Objective-C, los bloques también se pueden utilizar en C y C++ cuando se programa en la plataforma de Apple. |
OpenSCAD | Y | La compatibilidad con funciones literales se introdujo con la versión 2021.01. [37] |
Pascal | N | |
Perl | Y | [38] |
PHP | Y | A partir de PHP 5.3.0, se admiten funciones anónimas verdaderas. [39] Anteriormente, solo se admitían funciones anónimas parciales, que funcionaban de manera muy similar a la implementación de C#. |
PL/YO | N | |
Pitón | Y | Python admite funciones anónimas a través de la sintaxis lambda, [40] que solo admite expresiones, no declaraciones. |
R | Y | |
Raqueta | Y | [41] |
Raku | Y | [42] |
Rexx | N | |
Juego de rol | N | |
Rubí | Y | Las funciones anónimas de Ruby, heredadas de Smalltalk , se denominan bloques . [43] |
Óxido | Y | [44] |
Escala | Y | [45] |
Esquema | Y | |
Charla informal | Y | Las funciones anónimas de Smalltalk se llaman bloques . |
ML estándar | Y | [46] |
Rápido | Y | Las funciones anónimas de Swift se denominan cierres. [47] |
Mecanografiado | Y | [48] |
Mecanógrafo | Y | [49] |
Tcl | Y | [50] |
Vala | Y | [50] |
Visual Basic .NET versión 9 | Y | [51] |
Visual Prolog versión 7.2 | Y | [52] |
Lenguaje Wolfram | Y | [53] |
Zig | N | [54] |
... fue introducido por Alonzo Church en la década de 1930 como una notación precisa para una teoría de funciones anónimas.
Una cita es una función anónima (un valor que denota un fragmento de código) que se puede utilizar como valor y llamar mediante los combinadores fundamentales.