Currying (Currificación): definición y uso en matemáticas y programación
Currying (currificación): descubre cómo transformar funciones de varios argumentos en cadenas de funciones—aplicaciones en matemáticas, cálculo λ y programación (Haskell, ML).
El currying es una técnica utilizada en matemáticas y ciencias de la computación que consiste en cambiar una función que toma varios argumentos en una serie de funciones que toman cada una un argumento. Los matemáticos Moses Schönfinkel y Gottlob Frege sentaron las bases de esta técnica, que lleva el nombre de Haskell Brooks Curry. El currying se utiliza en el cálculo Lambda. Algunos lenguajes de programación, como ML y Haskell dicen que las funciones sólo pueden tener un argumento.
Definición formal
Formalmente, dado una función f de dos variables f: A × B → C, su versión currificada es una función curry(f): A → (B → C). Es decir, en lugar de recibir ambos argumentos a la vez, la función recibe el primer argumento y devuelve otra función que espera el segundo. Esta idea se extiende a cualquier número de argumentos: una función de n argumentos se transforma en una cadena de n funciones de un solo argumento.
Ejemplos simples
Matemáticamente, si add(x, y) = x + y, la versión currificada sería add_curry(x) = (y ↦ x + y). En código:
Haskell (donde las funciones son currificadas por defecto):
add :: Int -> Int -> Int add x y = x + y -- Se puede usar como (add 2) que devuelve una función que suma 2 a su argumento.
JavaScript (versión manual):
const add = x => y => x + y; const add2 = add(2); console.log(add2(3)); // 5
Python (anidando funciones):
def add(x): def add_y(y): return x + y return add_y add2 = add(2) print(add2(3)) # 5
Currying vs. aplicación parcial
- Currying transforma una función que toma varios argumentos en una secuencia de funciones unarias. Es una transformación estructural.
- Aplicación parcial (partial application) consiste en fijar uno o varios argumentos de una función para producir otra función con menos argumentos. Por ejemplo, a partir de una función f(x, y, z) crear f'(y, z) = f(2, y, z) fijando x=2.
Son conceptos relacionados: una función currificada facilita la aplicación parcial porque se pueden suministrar argumentos uno a uno.
Implementación práctica
En lenguajes con soporte nativo (Haskell, ML), las funciones se piensan y se escriben naturalmente en forma curried. En lenguajes imperativos o orientados a objetos se puede implementar una función genérica curry que transforme una función de N argumentos en su versión curried, y otra uncurry para la transformación inversa.
Ejemplo de una implementación genérica de curry en JavaScript (esquema básico):
function curry(fn) { return function curried(...args) { if (args.length >= fn.length) { return fn.apply(this, args); } else { return function(...more) { return curried.apply(this, args.concat(more)); } } }; } Ventajas y limitaciones
- Ventajas:
- Facilita la composición de funciones y el estilo funcional (por ejemplo, programación en estilo point-free).
- Permite crear funciones especializadas a partir de funciones generales (reutilización mediante aplicación parcial).
- Mejora la legibilidad en casos funcionales donde se encadenan transformaciones.
- Limitaciones y consideraciones prácticas:
- Puede introducir sobrecarga de llamadas (pequeño coste en tiempo y memoria por la creación de funciones intermedias).
- En APIs o bibliotecas que esperan funciones de múltiples argumentos, la integración puede requerir adaptación.
- La detección de aridad (número de parámetros) puede no ser fiable en algunos entornos dinámicos.
Usos comunes
- Configuración: crear funciones específicas a partir de una función general pasando parámetros de configuración primero.
- Manejo de eventos: fijar contexto o datos en handlers sin crear closures ad-hoc cada vez.
- Composición y tuberías de transformación de datos en programación funcional.
Historia y relación con el cálculo lambda
La idea proviene de la lógica y el cálculo lambda. Moses Schönfinkel introdujo conceptos de combinatoria lógica y Haskell B. Curry desarrolló y difundió estas ideas; de ahí el nombre. En el cálculo lambda, cualquier función de múltiples argumentos se puede representar naturalmente como una función curried mediante el uso de funciones anidadas (lambda abstractions), lo que facilita pruebas formales y transformaciones en compiladores funcionales.
Conclusión
El currying es una técnica fundamental en la programación funcional y la teoría de funciones. Aunque su uso y beneficio varían según el lenguaje y el contexto, entender cómo transformar funciones y cómo aprovechar la aplicación parcial mejora la modularidad y expresividad del código.
Preguntas y respuestas
P: ¿Qué es el curry?
R: El currying es una técnica utilizada en matemáticas e informática que consiste en transformar una función que toma varios argumentos en varias funciones que toman cada una un argumento.
P: ¿Quién sentó las bases del currying?
R: Los matemáticos Moses Schönfinkel y Gottlob Frege sentaron las bases de la técnica del currying.
P: ¿Quién es Haskell Brooks Curry y qué relación tiene con el currying?
R: Haskell Brooks Curry es un matemático que da nombre a la técnica del currying.
P: ¿Qué es el cálculo lambda?
R: El cálculo lambda es un sistema formal de lógica matemática e informática que se utiliza para expresar la computación.
P: ¿Qué función desempeña el currying en el cálculo Lambda?
R: El currying se utiliza en el cálculo Lambda para reducir funciones con múltiples argumentos a una serie de funciones con un único argumento.
P: ¿Existen lenguajes de programación que restrinjan las funciones a un único argumento?
R: Sí, algunos lenguajes de programación como ML y Haskell tienen la restricción de que las funciones sólo pueden tener un argumento.
P: ¿Por qué lenguajes de programación como ML y Haskell restringen el número de argumentos que pueden tomar las funciones?
R: Esta restricción está motivada por la simplicidad y flexibilidad que aporta el currying. Al tener funciones con un solo argumento, pueden ser fácilmente compuestas y combinadas, dando lugar a un código más conciso y reutilizable.
Buscar dentro de la enciclopedia