Tanto en matemáticas como en informática, las funciones de orden superior son aquellas que cumplen, al menos, una de estas condiciones:
- Esperan como argumento/s una o más funciones.
- Devuelven una función como resultado.
Ejemplos en matemáticas son la derivada y la antiderivada o función primitiva.
En informática son la esencia de los lenguajes funcionales, pero también aparecen en lenguajes de otros paradigmas. Este es un ejemplo en el lenguaje Scheme en el que la función (f x) recibe un argumento y devuelve una función:
(define (f x) (lambda (y) (+ x y))) (display ((f 3) 7))
Puede ejecutarse aquí para ver el resultado.
Cuando nació Javascript, a algunos programadores les pareció un lenguaje orientado a objetos fallido1, sobretodo porque, por razones comerciales, se le puso un nombre que lo asocia con Java. Desconozco si su creador estuvo muy de acuerdo con ese nombre pues, tal y como se diseño este lenguaje, da bastante juego a la programación funcional. En el siguiente ejemplo, el método filter() es una función de orden superior, pues espera recibir una función como parámetro:
function isPrime(x){ if (x === 2) { return true; } let test = x%2 !== 0; let i = 3; stop = Math.floor(Math.sqrt(x)); // Raíz entera de x while (test && i <= stop) { test = x%i !== 0; i = i + 2; } return test; } const numbers = [47, 139, 137, 213, 2, 3, 45, 1515]; const primeNumbers = numbers.filter(isPrime); console.log(primeNumbers);
Lo que este programa hace es filtrar la formación de números naturales «numbers«, dejando sólo los que sean primos en «primeNumbers«. Cada elemento de «numbers» será evaluado por la función «isPrime» mediante la criba de Eratóstenes. El lector puede ejecutarlo accediendo a la consola del navegador pulsando F12 y modificar el valor de «numbers» con los números (o el número) que quiera saber si son primos o no.
Este tipo de funciones están en prácticamente todos los lenguajes modernos, incluso en los que no se tuvo en cuenta el paradigma funcional en el momento de su creación. Es el caso de PHP, donde podemos encontrar una gran cantidad de funciones que esperan otra función, como es el caso de, por ejemplo, preg_replace_callback()2:
$capitalice = function($coincidencia) { return strtoupper($coincidencia[1]); }; echo preg_replace_callback('~-([a-z])~', $capitalice, 'hola-mundo');
Además de usar las implementadas en funciones y métodos propios del lenguaje, también podemos crear las nuestras, de forma parecida a un lenguaje completamente funcional. En Javascript, la Wikipedia nos ofrece el siguiente ejemplo:
const twice = (f, v) => f(f(v)); const add3 = v => v + 3; console.log(twice(add3, 7));
Lo mismo es posible en PHP:
$twice = function($f, $v) { return $f($f($v)); }; $f = function($v) { return $v + 3; }; echo($twice($f, 7));
La programación funcional pretende tratar la programación como la evaluación de funciones matemáticas, paradigma muy diferente a la programación imperativa, basada en estados y en instrucciones que lo cambian. Tal vez las características funcionales que tienen algunos lenguajes puedan ayudarnos a introducirnos en un paradigma, el funcional, que nos exige una forma muy distinta de enfocar los problemas.
1 Todavía hoy en día, y a pesar de los cambios que ha sufrido en los últimos ECMA, sigue despertando las críticas de los programadores que, debido a su nombre, esperan que se comporte como un lenguaje completamente orientado a objetos, como Java, y se dan de bruces contra la realidad.
2 El parámetro que recibe la función contenida en $capitalize son las coincidencias que encuentre la expresión regular.