Programación Funcional¶
Paradigmas de programación¶
Python es un lenguaje de programación interpretado cuya filosofía hace hincapié en la legibilidad de su código. Se trata de un lenguaje de programación multiparadigma, ya que soporta orientación a objetos, programación imperativa y, en menor medida, programación funcional.
Quiere decir que acepta diversas formar de trabajar con el lenguaje. Básicamente existen 3 paradigmas predominantes, o dicho de otra manera, 3 formatos globales de organizar un código.
Programación imperativa (estructurada), el código será ejecutado desde el principio del fichero al final sin seguir ningún tipo de desviación. Su mayor ventaja radica en su simplicidad y poco peso. Su peligrosidad es el código espagueti, archivos con centenares o miles de líneas donde solo unos pocos seres humanos son capaces de modificar y salir victoriosos.
Programación orientada a objetos (OOP o Object Oriented Programming), donde se encapsulan las variables y funciones en pequeños módulos capaces de clonarse y modificarse. Su punto fuerte es la capacidad de re-utilización y aislamiento para evitar problemas con otras funcionalidades. La parte negativa recae en la complejidad de crear buenos objetos y la depuración.
Programación funcional (FP o Functional programming), donde el código se reparte en sencillas funciones capaces de ser invocadas con variables u otras funciones. Su facilidad de uso por atomicidad logra un mantenimiento sólido y compatible con casi cualquier lenguaje. Además su inmutabilidad de variables evita gran parte de los problemas que si sufre la programación orientada a objetos.
Para seguir profundizando, leer el libro Clean Architecture - Robert C. Martin.
Principios de la programación funcional¶
Uso de funciones: Como su nombre indica, todo se construye por medio de funciones.
Funciones de primera clase: Las funciones son tratadas como una variable más. Incluso pueden ser devueltas.
Funciones puras: Totalmente predictivo, los mismos datos de entrada producirán los mismos datos de salida. Puedes sustituir el parámetro de entrada de sin que ello altere el flujo del programa.
Recursividad: Las funciones se pueden llamar a si mismas simplificando tareas como recorrer árboles de datos o la gestión de bucles controlados.
Inmutabilidad: No hay variables, solo constantes.
Evaluación perezosa (no estricta): En la programación funcional podemos trabajar con expresiones que no han sido evaluadas, o dicho de otra manera, podemos disponer de variables con operaciones cuyo resultado aún no se conoce.
Funciones¶
Las funciones en Python es que estas pueden ser asignadas a variables, lo cual nos abre la puerta a que funciones puedan ser usadas como argumento de otras funciones y que funciones retornen funciones.
# funcion suma de dos numeros
def suma(val1=0, val2=0):
return val1 + val2
resultado = suma(10,20)
print(resultado)
30
Funciones anónimas o lambdas¶
Habrá ocasiones en las cuales necesitemos crear funciones de manera rápida, en tiempo de ejecución. Funciones las cuales realizan una tarea en concreto, regularmente pequeña. En estos casos haremos uso de funciones lambda.
Una función lambda es una función anónima, una función que no posee un nombre. En Python la estructura de una función lambda es la siguiente.
terminal
lambda argumentos : cuerpo de la función
# un argumento
funcion = lambda a : 1+a
print(funcion(3))
4
# varios argumentos
suma = lambda val1=0, val2=0: val1 + val2
print(suma(10,20))
30
Función map¶
La función map permite aplicar una función a una secuencia de elementos como un iterable (Listas, tuplas, etc...). Es una forma rápida, limpia y, lo que es más importante, legible de realizar la operación.
La estructura de la función es la siguiente.
terminal
map(función a aplicar, objeto iterable)
#Obtener el cuadrado de todos los elementos en la lista.
def cuadrado(elemento=0):
return elemento * elemento
lista = [1,2,3,4,5,6,7,8,9,10]
resultado = list( map(cuadrado, lista) )
print(resultado)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Función filter¶
La función filter, es quizás, una de las funciones más utilizadas al momento de trabajar con colecciones. Cómo su nombre lo indica, esta función nos permite realizar un filtro sobre los elementos de la colección.
La estructura de la función es la siguiente.
terminal
filter(función a aplicar, objeto iterable)
#Obtener la cantidad de elementos mayores a 5 en la tupla.
def mayor_a_cinco(elemento):
return elemento > 5
tupla = (5,2,6,7,8,10,77,55,2,1,30,4,2,3)
resultado = tuple(filter( mayor_a_cinco, tupla))
print(resultado)
(6, 7, 8, 10, 77, 55, 30)

Función reduce¶
Usaremos la función reduce cuando poseamos una colección de elementos y necesitemos generar un único resultado. reduce nos permitirá reducir los elementos de la colección. Podemos ver a esta función como un acumulador.
La estructura de la función es la siguiente.
terminal
reduce(función a aplicar, objeto iterable)
#Obtener la suma de todos los elementos en la lista
lista = [1,2,3,4]
acumulador = 0;
for elemento in lista:
acumulador += elemento
print(acumulador)
10
Como observamos, para resolver el problema tuvimos que declarar una variable (acumulador). Variable que comienza con el valor de 0. Al recorrer la lista, el valor de nuestra variable incrementa. Su nuevo valor es el valor actual más el valor del elemento en la lista. Hasta aquí no creo que exista alguna duda.
Ahora veamos el mismo ejemplo utilizando la función reduce.
from functools import reduce
lista = [1,2,3,4]
def funcion_acumulador(acumulador=0, elemento=0):
return acumulador + elemento
resultado = reduce(funcion_acumulador, lista)
print(resultado)
10
Por cada elemento de la colección se ejecuta la función, funcion_acumulador. La función retorna la suma de los parámetros, este valor es almacenado en nuestro acumulador. Al finalizar la iteración de todos los elementos, reduce retornará el valor del acumulador.

Ejercicios¶
Ejercicio 01
Ocupando la notación lambda, crear las funciones operacionales básicas, es decir,
- suma
- resta
- multiplicaición
- división
- resto
- potencia
# respuesta
Ejercicio 02
Ocupando la notación map, crear una función que tome una lista de dígitos y analice si el número objetivo es primo o no.
# respuesta
Ejercicio 03
Ocupando la notación filter, crear una función que tome una lista de dígitos y analice si el número objetivo es un cuadrado perfecto o no.
# respuesta
Ejercicio 04
Ocupando la notación reduce, crear una función que tome una lista de dígitos y devuelva al número al que corresponden.
Por ejemplo [1,2,3] corresponde a el numero ciento veintitrés ($123$).
# respuesta