Programar en PHP con el estilo de Forth

Descripción del contenido de la página

Algunos ejemplos de cómo se puede aplicar el estilo del lenguaje de programación Forth a otros lenguajes muy diferentes, como PHP.

Etiquetas:

Para programar bien en Forth conviene olvidar cómo se hace en otros lenguajes. Intentar programar en Forth con el estilo de otros lenguajes sólo sirve para crear programas complejos, difíciles de depurar y difíciles de mantener. Yo mismo he escrito algunos monstruitos de ese tipo, escritos en Forth pero sin respetar el estilo y el espíritu de Forth.

Una de los beneficios de aprender a pensar en Forth es poder aplicar el estilo de Forth a la programación en otros lenguajes.

Recientemente he tenido que reescribir algún código en PHP de otro programador para adaptarlo a mis necesidades. Como en otras ocasiones, me he sorprendido a mí mismo aplicando varios principios de Forth en un lenguaje que no tiene nada en común con él. El resultado es un código más claro, más compacto, más legible, más rápido y más sencillo.

Muestro un par de ejemplos.

Ejemplo 1

Este es el código original:

<?
$count_max = 0;
$count_min = 999999999; // some big number

foreach($tag_counts as $tag) {
  if($tag["count"] > $count_max)
    $count_max = $tag["count"];

  if($tag["count"] < $count_min)
    $count_min = $tag["count"];
}
?>

Como se ve, se trata de encontrar los valores mínimo y máximo de una matriz. El programa parte de un valor máximo mínimo y un valor mínimo máximo; después recorre toda la matriz para comparar cada elemento dos veces, con el valor mínimo y con el valor máximo, y actualizar éstos si es necesario.

Lo primero que se me ocurrió para darle un poco de la sencillez característica de Forth fue utilizar como índice de la matriz uno de los dos datos que contenía cada elemento. Lo segundo, por supuesto, quitar los condicionales. Este es el resultado:

<?
$count_max = 0;
$count_min = 999999999; // some big number

foreach($tags_count as $tag=>$count)
{
  $count_max = $count > $count_max ? $count : $count_max;
  $count_min = $count < $count_min ? $count : $count_min;
}
?>

Así está mejor. Pero, ¿por qué recorrer toda la matriz en busca de los dos elementos que guardan el dato mayor y el dato menor? Puedo ordenar la matriz por ese dato; entonces el elemento menor quedará en la primera posición y el mayor en la última, y sólo tendré que tomarlos:

<?
asort($tags_count);
$count_min = reset($tags_count);
$count_max = end($tags_count);
?>

Esto ya tiene mejor aspecto. Así la matriz queda ordenada por valores, cosa que no ocurría en el original. Pero no importa porque en cualquier caso en la siguiente sección del programa necesitaría ordenarla por los índices con ksort($tags_count).

Pero aún se puede mejorar. ¿Por qué no dejar que una función de PHP haga el trabajo por nosotros?

<?
$count_min = min($tags_count);
$count_max = max($tags_count);
?>

Eso esta mucho mejor. Dos líneas de programa en lugar de ocho y ni una sola estructura de control; no es Forth, pero el es estilo de Forth.

Ejemplo 2

Este es el código original:

<?
$rango = $mayor - $menor;
if (0 == $rango) {
$rango = 1;
}
$incremento = ($maximo - $minimo)/$rango;
?>

Tras unas pinceladas del estilo de Forth, el código PHP adquiere este aspecto tan elegante:

<?
$incremento = ($maximo - $minimo) / max(1, $mayor-$menor);
?>

Una línea de programa en lugar de cinco y ni una sola estructura de control.

Conclusión

La mentalidad habitual de un programador de lenguajes como PHP y otros muchos (la mayoría de los lenguajes comparte los mismos principios) hace escribir cosas como haz el cálculo y si resulta así haz esto pero si no haz otra vez el cálculo y si resulta asá haz aquello pero si no haz otra vez el cálculo y...; Forth por el contrario enseña a calcular exactamente lo que se necesita (ni más ni menos) y a utilizar el resultado allí donde se necesita (ni antes ni después).

Un libro estupendo para aprender a pensar en Forth y aplicar sus principios a cualquier lenguaje de programación es Thinking Forth de Leo Brodie; está disponible gratuitamente en formato electrónico.