Implementando Mutaciones de Estado Inmutables con Generators en PHP
La inmutabilidad de estado es un principio clave en programación funcional y ayuda a prevenir efectos secundarios inesperados, facilitando la depuración y razonamiento del código. Tradicionalmente, PHP no ha sido el lenguaje más amigable para la inmutabilidad, pero podemos usar generators para simular mutaciones inmutables de manera eficiente y elegante.
La idea es crear un generator que reciba un estado inicial y una función de mutación. Cada vez que el generator produce un valor, representa un nuevo estado, derivado del anterior, pero sin modificar el estado original. Esto nos permite mantener un registro de estados históricos sin sobreescribir los datos originales.
<?php
/**
* Genera una secuencia de estados inmutables.
*
* @param mixed $initialState El estado inicial.
* @param callable $mutationFn Una función que recibe el estado anterior y devuelve el nuevo estado.
*
* @return Generator
*/
function immutableStateGenerator($initialState, callable $mutationFn): Generator
{
$currentState = $initialState;
yield $currentState; // El estado inicial es el primer valor
while (true) {
$currentState = $mutationFn($currentState);
yield $currentState; // Produce el nuevo estado
}
}
// Ejemplo de uso:
$initialValue = 0;
$increment = function ($state) {
return $state + 1;
};
$stateHistory = immutableStateGenerator($initialValue, $increment);
// Imprime los primeros 5 estados
for ($i = 0; $i < 5; $i++) {
echo "Estado " . ($i + 1) . ": " . $stateHistory->current() . "<br>";
$stateHistory->next(); // Avanza al siguiente estado
}
?>
En este ejemplo, la función `immutableStateGenerator` toma un estado inicial y una función anónima `increment` que incrementa el valor del estado en 1. Cada vez que llamamos a `$stateHistory->next()`, la función `increment` es ejecutada sobre el estado anterior, generando un nuevo estado que es devuelto por `$stateHistory->current()`. Es importante notar que el estado original `$initialValue` nunca es modificado, y cada `$stateHistory->current()` devuelve un nuevo valor.
Esta técnica es particularmente útil en escenarios donde se necesita un historial de estados, como en sistemas de undo/redo, o en el seguimiento de eventos y transformaciones de datos. La inmutabilidad nos asegura la consistencia de los datos y facilita la depuración, al poder rastrear los cambios de estado con precisión.
No hay comentarios:
Publicar un comentario