Programación Funcional en PHP: Nivel Avanzado
\n\nLa programación funcional (PF) es un paradigma en el que los cálculos se consideran como la evaluación de funciones matemáticas, y se evitan los cambios de estado y los datos mutables. Aunque PHP no fue diseñado originalmente como un lenguaje puramente funcional, a partir de la versión 7.4 y especialmente en PHP 8.x, ha recibido potentes herramientas para escribir código en estilo funcional. En este artículo, analizaremos conceptos avanzados de PF en PHP: desde funciones de orden superior hasta mónadas, con ejemplos prácticos y recomendaciones.
\n\n1. Funciones de orden superior y clausuras
\n\nLas funciones de orden superior son funciones que toman otras funciones como argumentos o las devuelven. En PHP, esto se implementa mediante funciones anónimas (clausuras) y las funciones integradas array_map, array_filter, array_reduce.
Ejemplo: función de devolución de llamada para filtrar
\n\n<?php\n$numbers = [1, 2, 3, 4, 5, 6];\n\n// Función de orden superior\n$filterEven = function(array $items, callable $callback): array {\n $result = [];\n foreach ($items as $item) {\n if ($callback($item)) {\n $result[] = $item;\n }\n }\n return $result;\n};\n\n// Función anónima predicado\n$isEven = fn($n) => $n % 2 === 0;\n\n$evenNumbers = $filterEven($numbers, $isEven);\n// Resultado: [2, 4, 6]\nprint_r($evenNumbers);\n?>\n\n\nEjemplo: fábrica de funciones (clausura con estado)
\n\n<?php\nfunction createMultiplier(float $factor): callable {\n // La clausura "recuerda" $factor\n return fn($number) => $number * $factor;\n}\n\n$double = createMultiplier(2);\n$triple = createMultiplier(3);\n\necho $double(5); // 10\necho $triple(5); // 15\n?>\n\n\nLas clausuras en PHP permiten capturar variables del ámbito externo mediante use (en PHP 7.4+ se pueden usar funciones flecha fn). Esto es la base para construir currificación y aplicación parcial.
2. Currificación y aplicación parcial
\n\nLa currificación es la transformación de una función de varios argumentos en una secuencia de funciones de un solo argumento. La aplicación parcial es la fijación de una parte de los argumentos de una función. PHP no tiene soporte integrado, pero esto es fácil de implementar.
\n\nEjemplo: currificación manual
\n\n<?php\n// Función normal\nfunction add(int $a, int $b): int {\n return $a + $b;\n}\n\n// Versión currificada\n$curriedAdd = function(int $a): callable {\n return function(int $b) use ($a): int {\n return $a + $b;\n };\n};\n\n$addFive = $curriedAdd(5);\necho $addFive(3); // 8\n?>\n\n\nEjemplo: función universal de currificación
\n\n<?php\nfunction curry(callable $fn, int $arity = null): callable {\n $reflection = new ReflectionFunction($fn);\n $arity = $arity ?? $reflection->getNumberOfRequiredParameters();\n\n $curry = function(...$args) use ($fn, $arity, &$curry) {\n if (count($args) >= $arity) {\n return $fn(...$args);\n }\n return function(...$nextArgs) use ($fn, $args, $arity, $curry) {\n return $curry(...array_merge($args, $nextArgs));\n };\n };\n\n return $curry;\n}\n\n$add = function(int $a, int $b, int $c): int {\n return $a + $b + $c;\n};\n\n$curriedAdd = curry($add);\n$result = $curriedAdd(1)(2)(3); // 6\necho $result;\n?>\n\n\nLa currificación es especialmente útil en la composición de funciones y la creación de versiones especializadas de funciones generales.
\n\n3. Composición de funciones y patrones funcionales
\n\nLa composición de funciones es la creación de una nueva función mediante la aplicación secuencial de varias funciones. El resultado de una función se pasa como entrada a la siguiente.
\n\nEjemplo: composición "de izquierda a derecha" (pipe)