Programación funcional
Índice:
- Introducción
- ¿Qué es?
- Funciones puras e impuras
- Lambda
- Mapas
- Filtros
- Funciones generadoras
- Funciones decoradoras
- Funciones recursivas
Introducción
Hasta el momento, hemos trabajamos con un paradigma (una forma de modelar y diseñar programas) conocido como programación imperativa.
Este tipo de programación es la hace uso de declaraciones, bucles y funciones.
Recordemos que, al comienzo del taller, habíamos dicho que Python es un lenguaje que soportaba múltiples paradigmas.
Ahora vamos a ingresar a conocer (de manera superficial) un nuevo paradigma que es la Programación Funcional.
¿Qué es la programación funcional?
Es un estilo de programación que hace uso, y se construye, en torno a las funciones.
Estas funciones son conocidas como funciones de alto orden o funciones de orden superior.
La característica que tienen estas funciones de orden superior es la de tomar como argumentos de entrada otras funciones o bien devolver una función como retorno.
|
|
Conociendo a las funciones puras e impuras.
Cuando trabajamos con programación funcional buscamos hacer uso de las funciones puras.
Estas funciones son aquellas retornan un valor, el cual depende de los parámetros de entrada, y no se observan ningún efecto secundario.
|
|
|
|
Esta función anterior es considerada impura debido a que tiene un efecto secundario. Modifica la lista (miLista).
Lambdas
Se le dice lambda es una función que toma uno o más argumentos pero tiene solo una expresión implementada en ella (siempre se trata de una implementación simple que pueda expresarse en no más de una línea de código.
Estas funciones son anónimas.
Para ir aclarando estos conceptos arrancaremos definiendo una función mediante el operador def como venimos realizando hasta el momento.
|
|
Esta función se puede hacer en menos líneas de código.
|
|
Esta misma función se puede “acomodar” en una sola línea
|
|
Entonces esta función:
|
|
Puede ser escrita en forma de función lambda de la siguiente manera haciendo uso del operador lambda
|
|
La estructura de una función lambda es la siguiente:
|
|
donde argumentos son los “valores” con los que la función opera y expresión es la operación o implementación en si misma.
Se suele asignar una función lambda a una variable de la siguiente forma:
|
|
Veamos un ejemplo práctico
|
|
Un ejemplo con dos argumentos
|
|
Como vimos, las funciones lambda siempre son una expresión que cabe en una línea, nunca un bloque de código. Además, decíamos que eran anónimas, esto se debe a que no tienen un nombre (o identificar) explicito para llamarlas. Dicho de otra manera, son funciones sin nombre.
Mapas
Un mapa es una función que necesita de dos argumentos: una función y un objeto iterable (listas, diccionarios,etc.). El objetivo del mapa es aplicar la función a cada elemento del objeto iterable.
Tiene la siguiente forma.
|
|
Imaginemos que tengo una lista de números y quiero restarle 1 a cada elemento.
|
|
Una buena idea es aplicar el concepto de lambdas al usar mapas
|
|
Filtros
Un filtro es otra función parecida a mapa. Necesita dos argumentos: una función y un iterable. La diferencia radica en que el filtro va a remover elementos que NO cumplan cierta condición, por lo tanto esa función siempre tiene que ser condicional. Tiene la forma:
|
|
Imaginemos el siguiente ejemplo:
Dada una lista de números enteros queremos remover aquellos que son pares.
|
|
A los filtros también resulta conveniente escribirlos en lambdas
|
|
Generadores
Normalmente al momento de crear una lista la declaramos vacía y luego con un bucle la vamos llenando.
|
|
Como se ve en el ejemplo anterior, los valores generados los vamos almacenando en una estructura y una vez finalizado el bucle podemos trabajar con ellos. Los generadores son funciones que nos permiten definir una iteración, por ejemplo una secuencia de 0 a 9, pero de a un elemento a la vez.
|
|
Podemos usar una función generadora y crear una lista de la siguiente manera
|
|
Dijimos que podemos ir generando la secuencia de uno en uno, esto lo podemos comprobar de la siguiente forma
|
|
En resumen, los generadores nos permiten declarar una función que se comporta como iterador y puede ser usada en bucle.
La diferencia principal radica en que el generador va a ir cediendo valores en tiempo de ejecución.
El uso de funciones generadoras aumenta la performance del programa y baja el consumo de memoria.
Otra ventaja es que se pueden ir usando los elementos a medida que se van creando.
Decoradores
Son funciones que nos permiten agregar funcionalidades a otra función.
La idea es no modificar la función original.
Ejemplo:
Tenemos la siguiente función que muestra un texto en pantalla
|
|
Ahora bien, queremos hacer de este texto algo “más vistoso” sin modificar la función original.
Para ello usamos las funciones decoradoras.
|
|
************
Hola alumnes
************
Hay una forma más simple de invocar a decoradores en Python que es la siguiente:
|
|
************
Hola alumnes
************
Recuerde que una función puede tener múltiples decoradores
Recursividad
La recursividad es un concepto fundamental en la programación funcional.
Hace referencia a funciones que se invocan a si mismas con el fin de resolver algún problema.
Hay un ejemplo clásico en este tema y es el factorial.
|
|
5
4
3
2
120
Las funciones recursivas siempre tienen que tener un caso base, es decir una condición que se cumpla para que se detenga la ejecución de la recursividad.
|
|