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. 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.
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.
Usos y Funciones 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.
Clasificación 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:
>>> a = ['casa', 'automóvil', 'avión'] >>> a.sort(lambda x,y: cmp(len(x), len(y))) >>> print(a) ['casa', 'avión', 'automóvil'] La función anónima en este ejemplo es la expresión lambda: lambda x,y: cmp(...) 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):
>>> a = [10, 'number', 11.2] >>> a.sort(lambda x,y: cmp(x.__class__.__name__, y.__class__.__name__)) >>> print(a) [11.2, 10, 'number'] 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".
Clausuras
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.
def comp(threshold): return lambda x: x < threshold 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) True True False False
>>> print func_b(5), func_b(8), func_b(13), func_b(21) True True True False 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
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).
>>> def divide(x, y): ... return x / y
>>> def divisor(d): ... return lambda x: divide(x, d)
>>> mitad = divisor(2) >>> tercio = divisor(3)
>>> print mitad(32), tercio(32) 16 10
>>> print mitad(40), tercio(40) 20 13
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".
Funciones de orden superior Python 2.x incluye varias funciones que toman funciones anónimas como argumento. Esta sección describe algunos de ellos.
Mapeo 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.
>>> a = [1, 2, 3, 4, 5, 6] >>> print map(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 (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:
>>> a = [1, 2, 3, 4, 5, 6] >>> print [x*x for x in a] [1, 4, 9, 16, 25, 36]
Filtro La función de filtro devuelve todos los elementos de una lista que al ser evaluados utilizando una determinada función regresan True.
>>> a = [1, 2, 3, 4, 5, 6] >>> print filter(lambda x: x % 2 == 0, a) [2, 4, 6]
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:
>>> a = [1, 2, 3, 4, 5, 6] >>> print [x for x in a if x % 2 == 0] [2, 4, 6]
Doblar 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:
>>> a = [1, 2, 3, 4, 5] >>> print reduce(lambda x,y: x*y, a) 120
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.
Lista de lenguajes 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.
Tabla con los lenguajes y sus soportes Lenguaje Soporte Notas ActionScript Ada Las funciones de expresión forman parte de Ada2012 ALGOL 68 Brainfuck Bash Se ha creado una biblioteca para admitir funciones anónimas en Bash. C El apoyo se proporciona en Clang y junto con el compilador-rt lib LLVM. El apoyo de GCC se da para una implementación de macros que permite la posibilidad de uso. C# C++ Como parte del estándar C++11. CFML A partir de Railo 4, ColdFusion 10 Clojure COBOL Micro Focus es un lenguaje COBOL gestionado no estpándar el cual soporta lambdas, a los cuales se les llaman delegados / métodos anónimos. Curl D Dart Delphi Dylan Eiffel Elixir Erlang F# Factor Las "Citas" soportan esta función. Fortran Frink Go Gosu Groovy Haskell Haxe Java Supported in Java 8. Ver la sección limitaciones en Java para detalles. JavaScript Julia Lisp Logtalk Lua MUMPS Mathematica Maple MATLAB Maxima OCaml Octave Object Pascal Delphi, un dialecto de Object Pascal, soporta funciones anónimas (formalmente llamados métodos anónimos ) de forma nativa desde Delphi 2009. El dialecto Pascal llamado Oxygene también los soporta. Objective-C (Mac OS X 10.6+) Son llamados bloques; en adición a Objective-C, los bloques también pueden ser usados en C and C++ cuando se programa dentro de la plataforma Apple. Pascal Perl PHP A partir de PHP 5.3.0, se admiten funciones verdaderamente anónimas. Anteriormente, solo se admitían funciones anónimas parciales, que funcionaban como la implementación de C#. PL/I Python Python soporta funciones anónimas a través de la sintaxis lambda, que soporta solo expresiones, no declaraciones. R Racket Rexx RPG Ruby Las funciones anónimas de Ruby, heredadas de Smalltalk, se llaman bloques. Rust Scala Scheme Smalltalk Las funciones anónimas de Smalltalk se llaman bloques. Standard ML Swift Las funciones anónimas de Swiftson son llamadas clausuras. TypeScript Tcl Vala Visual Basic .NET v9 Visual Prolog v 7.2 Wolfram
Ejemplos Numerosos idiomas soportan funciones anónimas, o son capaces de realizar alguna función similar.
C (extensión no estándar) 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.
GCC 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:
( { Tipo_de_retorno Nombre_de_la_función_anónima(parámetros) { cuerpo_de_la_función} Nombre_de_la_función_anónima; } )