Cookies

Esta web utiliza cookies para obtener datos estadísticos de la navegación de sus usuarios. Si continúas navegando consideramos que aceptas su uso.

PHP Funcional

Programación funcional. ¿Qué es ese paradigma del que se habla tanto últimamente? En este post vamos a tratar de explicar más o menos de que trata la programación funcional, y vamos a poner algún ejemplo en PHP. Sí, en PHP.

El concepto

La programación funcional no es una corriente moderna, ya tiene sus años con la aparición del Lambda Cálculo con lenguajes como Lisp.

Se trata básicamente de que tenemos a nuestra disposición estructuras de datos y funciones, añadiendo comodidades al lenguaje de programación en cuestión para utilizar funciones como variables o pasarlas como argumento a otra función. Otros mecanismos que se suelen relacionar con la programación funcional suele ser el Currying la inicialización perezosa (Lazy Initialization) y la inmutabilidad.

El concepto es bastante abstracto, y es dificil de entender sin un ejemplo, así que mostremos un primer uso básico de programación funcional, utilizando una función como argumento de otra función.

Un ejemplo

<?php

function index_and_value_are_even($arr)
{
    $result = [];
    foreach($arr as $index => $value) {
        if ($value % 2 == 0 && $index % 2 == 0) {
            $result[$index] = $value;
        }
    }

    return $result;
}

var_export(index_and_value_are_even([1, 2, 3]));

Este fragmento de código devuelve un array vacío, dado que nunca tenemos un valor par en el array pasado como argumento que tenga también un índice par.

En mil aplicaciones se pueden ver fragmentos de código así, recorriendo un array y aplicando una operación de filtrado sobre él. No es que sea una mala manera de hacerlo, es sencillo de entender y estándar, aunque sin darnos cuenta estamos reinventando la rueda y utilizando mucha más sintaxis de la necesaria, repetitiva y poco expresiva.

Veamos como sería la función anterior usando programación funcional.

<?php
function is_even($n)
{
    return $n % 2 == 0;
}

function index_and_value_are_even($arr) {
    return array_filter($arr, function($index, $value) {
        return is_even($index) && is_even($value);
    });
}

¿Mucho mejor, no? Aunque en esto de la programación para gustos los colores, a mi parecer el código es mucho más expresivo utilizando la programación funcional.

Como comentamos en el propio post, hay un problema con esta solución y es que PHP no ofrece una función nativa para filtrar arrays que nos proporcione el índice o clave en la función argumento. Existe la función array_filter pero solo permite filtrar por el valor. Esto no acaba de ser lo óptimo, ya que sobretodo si utilizamos arrays como hashes, la clave puede tener mucho que ver en cuanto a nuestra operación de filtrado. De todas formas, es trivial desarrollar por nuestra parte ésta función.

<?php

function array_filter_with_indices(array $arr, callable $fn)
{
    $result = [];
    foreach($arr as $key => $value) {
        if ($fn($key, $value)) {
            $result[$key] = $value;
        }
    }

    return $result;
}

Sí, una implementación muy simple. Ahora cada vez que queramos quedarnos con parte de un array podemos utilizar nuestra función filter con una función anónima como argumento que nos diga que condiciones queremos que cumplan los objetos. Hay que tener cuidado en que si le pasamos como argumento un array no hash en el que nos importe mantener los índices cohesionados, la función va a devolver el par índice valor original, por lo que si toma los elementos en las posiciones 1 y 25 va a devolver un array tal que así.

<?php
[
    1 => 'valor',
    25 => 'valor'
];

Destacar de este fragmento de código el uso del Type Hinting, un mecanismo poco conocido de PHP con el que hacemos el lenguaje un poco estático añadiendo type checking en los argumentos de una función, algo que es muy útil en ciertas ocasiones. Como podemos ver, existe la posibilidad de decir que una función o método recibe algo callable es decir, que se puede llamar. Este tipo de type hinting se ha añadido en la versión 5.4, por lo que no puede usarse en versiones anteriores del lenguaje.

En próximos posts implementaremos más funciones básicas de la programación funcional en PHP, y examinaremos más mecanismos que ofrece el lenguaje para desarrollar utilizando la programación funcional.