Home » Cursos » Swift avanzado (I): Funciones curried o parcializadas
Funciones Curried (Parcializadas)

Swift avanzado (I): Funciones curried o parcializadas

Empezamos una nueva sección de artículos que cubrirán aspectos avanzados del lenguaje Swift. Herramientas que podemos usar para mejorar nuestros programas y conseguir una mejor lógica y que van más allá de los conceptos básicos para comenzar a usar el lenguaje, que es lo que hemos visto hasta ahora. Si ya tienes experiencia en el lenguaje te serán muy útiles y si no, también puedes intentar explorarlo y descubrir la potencia de estas funciones avanzadas.

En este primer artículo vamos a tratar un concepto de la programación funcional: las funciones curried o parcializadas. ¿Funciones al curry? Bueno, en realidad deben su nombre al matemático y lógico estadounidense Haskell Brooks Curry, nacido en el año 1900 e investigador en la teoría de sistemas y lógica combinatoria, que dio lugar a los conceptos más básicos de la programación funcional. El lenguaje de programación Haskell lleva su nombre y la aplicación de la parcialización de funciones se conoce en su nombre como “currificación”.

Swift, al estar diseñado sobre la base de múltiples lenguajes como el propio Python (quien a su vez debe sus conceptos de programación funcional al Haskell) ha heredado varios conceptos básicos de programación funcional, como este que vamos a ver ahora u otros tan interesantes como reduce, filter o map, que veremos más adelante más en detalle.

Concepto

Una función currificada o parcializada es aquella que recoge más de un conjunto de parámetros de entrada en distintos momentos. La currificación recoge un primer conjunto de parámetros y devuelve como resultado una función que espera el o los siguientes conjuntos de los mismos, precargando los ya indicados como una instanciación parcial.

Por ejemplo, aplicado a una suma sería algo así:

Cuando invocamos esta función (que tiene un conjunto de dos parámetros de entrada diferentes en dos grupos de paréntesis diferentes) su resultado es una función intermedia que tendrá asignado el primer conjunto y pedirá el resto como parámetros. Para realizar la primera invocación de una función currificada hemos de asignarla a una variable o constante que almacenará como tipo de la misma una función.

Si miramos el tipo de suma veremos que es del tipo (y:Int) -> Int, es decir, es una función de un solo parámetro. Ahora, en suma tenemos un código (aunque no lo vemos) equivalente a si tenemos una función con el siguiente código:

De esta forma podemos entender qué ha hecho la currificación. Hemos guardado en una variable una función cuyo primer parámetro se ha precargado. Si creamos una nueva constante llamada suma3, como esta:

Tendríamos una nueva “instancia” (nótense las comillas) que nos permitiría sumar 3 a cualquier número (la constante suma3) igual que ya tenemos una que nos permite sumar 2 a cualquier número (la constante suma2). Ambas, obtenidas de la misma función currificada.

Ahora podemos usar suma2 o suma3 como si fueran una función.

Si evaluamos el valor de s2mas5, veremos que es 7 (la suma de 5 que hemos pasado como parámetro más el 2 que habíamos puesto en la x) y en el caso de s3mas4 el resultado sería 8, porque el valor al crear la constante suma3 desde la función currificada fue 3.

La currificación como base de la instanciación de clases

El concepto de la currificación es usado por Swift en su propia especificación para la instanciación de funciones dentro de clases. De hecho, la programación funcional nos permite asignar a una constante una función que pertenezca a la definición de una clase y no a un objeto de la misma. A través de la currificación, enviando dos parámetros independientes nos permite aplicar dicha función a cualquier instancia de la clase. Esto nos permite ver como la programación funcional y el concepto de la currificación, son parte intrínseca de Swift.

Vamos a suponer que tenemos un personaje de un juego que tiene una vida de 100 como valor y creamos nuestra clase.

Y ahora vamos a crear dos instancias de personajes diferentes.

Todo muy simple hasta aquí. Pero ahora en vez de invocar la función quitarVida en cualquiera de los dos personajes creados, vamos a crear una variable que contenga la función de la definición de la clase.

El tipo inferido a daño es una función. Y si ahora invocamos la currificación de la función daño con un conjunto de dos variables, donde la primera sea el objeto que instancia al personaje al que queremos dañar y la segunda la cantidad de daño, vamos a ver qué sucede.

Estamos diciendo que ejecute daño sobre elfo con valor de 20 y sobre enano con valor de 30. Y si ahora evaluamos qué valor tiene la vida de cada uno veremos que esta ha descendido en función de lo que hemos indicado. Hemos aplicado una función de la propia definición de una clase sin instanciar sobre un objeto ya instanciado.

¿Por qué? Porque Swift emplea la currificación de manera interna (tal como estamos viendo) para realizar la instanciación de métodos. Cuando nosotros llamamos al método quitarVida de un objeto instanciado de la clase Personaje como enano, lo que hace en realidad es usar la parcialización para crear una referencia a la función de la clase y luego aplicarle dicha función a la instancia a través de este concepto de programación funcional.

La currificación no solo se permite en dos niveles, podemos usar varios conjuntos e ir asignando valores de uno en uno o varios a la vez, creando diferentes escaladas de asignación de las funciones y hacer cosas como estas.

Las posibilidades son tantas como podamos imaginar y las aplicaciones casi infinitas. Solo hay que buscar casos donde aplicar este concepto, uno de los muchos y muy interesantes que la programación funcional nos brinda.

Resumiendo

Es complicado, sobre todo si no tenemos conceptos básicos de lógica y desarrollo funcional, pero la currificación es sumamente práctica y al estar tan embebida dentro del propio Swift, su uso nos proporciona muchas y muy interesantes opciones a la hora de desarrollar algoritmos que den solución a nuestros desarrollos.

Como siempre, y esta vez más aun, os invitamos a que le deis más de una vuelta, probéis y nos vemos en el próximo artículo. Hasta entonces, Good Apple Coding.

Acerca de Julio César Fernández

Analista, consultor y periodista tecnológico, desarrollador, empresario, productor audiovisual, actor de doblaje e ingeniero de vídeo y audio.

Otras recomendaciones

Lecciones Prototipos (I): UITableView

Lecciones por prototipos (I): Vistas de tabla (UITableView)

Primera lección por prototipos, un nuevo e innovador contenido. A veces, lo normal es que nos perdamos sin terminar de entender qué es o cómo funcionan los componentes que forman parte de una app o un juego. Para este caso hemos creado las lecciones por prototipos. Una exploración básica de conceptos esenciales a través de prototipos en Playground que podemos probar con Swift Playgrounds en el iPad o con Xcode 8. En esta primera lección abordamos las UITableView (vistas de tabla). Un elemento esencial en la mayoría de apps de iOS que muchas veces no es entendido desde su base y por lo tanto, provoca un mal uso de las mismas.