Programación declarativa: cuando el qué es más importante que el cómo

Da igual que se trate de la programación de una aplicación, un software de IoT o un juego de ordenador: antes de que los desarrolladores escriban las primeras líneas de código, deben tomar una decisión fundamental: ¿qué lenguaje de programación van a utilizar? Existen diversos lenguajes a su disposición, pero, si se contemplan con perspectiva, todos se basan en dos paradigmas de programación fundamentales: la programación declarativa y la programación imperativa.

¿Qué es la programación declarativa?

No hay consenso sobre la definición de este paradigma, pero todas las explicaciones coinciden en algo: lo que destaca de los lenguajes de programación declarativa es que siempre se describe el resultado final deseado, en lugar de mostrar todos los pasos de trabajo. Para alcanzar el objetivo, en la programación declarativa se determina automáticamente la vía de solución. Esto funciona siempre y cuando las especificaciones del estado final se definan claramente y exista un procedimiento de ejecución adecuado. Si se dan las dos condiciones, la programación declarativa es muy eficiente.

Como la programación declarativa no determina el “cómo”, sino que funciona a un nivel de abstracción muy alto, este paradigma deja margen para la optimización. Si se ha desarrollado un procedimiento de ejecución mejor, el algoritmo integrado lo encuentra y lo aplica. En este sentido, el paradigma está muy preparado para el futuro porque, al escribir el código, no es necesario determinar el procedimiento según el cual se alcanza el resultado.

Los lenguajes de programación declarativa más conocidos son:

  • Prolog
  • Lisp
  • Haskell
  • Miranda
  • Erlang
  • SQL (en un sentido amplio)

Los distintos lenguajes declarativos se pueden subdividir, a su vez, en dos paradigmas, el de la programación funcional y el de la programación lógica.

Sin embargo, es habitual que en la práctica los límites se difuminen y que, a la hora de solucionar problemas, se apliquen tanto elementos de la programación imperativa, con sus subtipos de programación procedimental, modular y estructurada, como de la programación declarativa.

Programación declarativa e imperativa

El paradigma de programación imperativa (paradigma orientado a instrucciones) es el más antiguo de los dos paradigmas fundamentales. A diferencia de en la programación declarativa, en este caso, el desarrollador determina con precisión en el código fuente los pasos que debe dar el ordenador para alcanzar el resultado. Se prioriza, pues, el “cómo” de la vía de solución. Este enfoque se puede encontrar, por ejemplo, en Java, Pascal o en C. Por el contrario, en la programación declarativa se describe directamente el “qué” de la solución.

Tomemos como ejemplo la construcción de muebles: mientras que la programación imperativa ofrece las instrucciones de montaje, la programación declarativa ofrece una imagen del mueble ya montado como muestra.

En lugar de dejar abierta la ejecución con funciones, en la programación imperativa existen variables que se modifican durante el tiempo de ejecución. Esto hace que el código sea más largo, pero también más fácil de entender que la forma abreviada y abstracta del lenguaje declarativo.

Ejemplo de programación declarativa

Un punto fuerte de la programación declarativa es su capacidad para describir problemas de forma más corta y precisa que el lenguaje imperativo.

Si se tiene que crear una lista con nombres, con la programación declarativa se puede describir en PHP con solo una línea de código, como vemos aquí abajo, mientras que el procedimiento imperativo necesita cinco líneas.

Programación imperativa:

$listaparticipantes = [1 => 'Peter', 2 => 'Hans', 3 => 'Sarah'];
$nombres = [];
foreach ($listaparticipantes as $id => $apellido) {
    $nombres[] = $apellido;
}

Programación declarativa:

$nombres = array_values($listaparticipantes);

Ventajas e inconvenientes de los lenguajes de programación declarativa

El estilo de programación declarativa se utiliza hoy en día en una multitud de casos y, en ocasiones, en estilo puro. Sin embargo, el enfoque no es apropiado para todos los usos.

El código declarativo destaca por su alto nivel de abstracción. Esto permite a los desarrolladores representar programas complejos de forma comprimida. Sin embargo, cuanto más extensa sea la ejecución, mayor será el riesgo de que el código se vuelva tan enrevesado que solo sea legible para el desarrollador que lo escribió. Para las empresas que quieren aplicar el mantenimiento y desarrollo de las aplicaciones con independencia de la persona que las desarrolló, esta situación puede suponer un peligro. En estos casos, los desarrolladores externos deberán esforzarse por leer el código declarativo hasta que hayan entendido la estructura y hayan resuelto los problemas.

No obstante, el nivel de abstracción de la programación declarativa también ofrece ventajas. Siempre que la ejecución se encuentre claramente separada del sistema mediante un algoritmo, el mantenimiento se podrá realizar con independencia del desarrollo de la aplicación. Las averías en el funcionamiento diario se reducen al mínimo. Al mismo tiempo, la optimización resulta más fácil, ya que el algoritmo utilizado es suficientemente abierto como para acceder a nuevos métodos. La desventaja del uso del algoritmo es que, dependiendo de determinadas características de los casos concretos de aplicación, una solución típica de este tipo a menudo resulta insuficiente.

Aunque de por sí no puede considerarse una desventaja, el modelo de la programación declarativa sí que presenta un desafío. Pensar en estados de solución es contrario al pensamiento natural del ser humano. Las personas pensamos en procesos que llevan a un objetivo, en lugar de partir de un objetivo e ir hacia atrás. En este sentido, se requiere de los desarrolladores un cambio de perspectiva y una familiarización que puede ralentizar, en un primer momento, las soluciones de los problemas. Sin embargo, una vez que se haya entrenado esta nueva forma de pensar, el enfoque declarativo puede desarrollar sus puntos fuertes.

Además, partir del desarrollo de la descripción del problema tiene la ventaja de que los equipos pueden esquematizar realmente rápido los modelos de soluciones. Por último, la programación concreta de la ejecución puede realizarse en un paso posterior. Para ello, el estilo declarativo de prototyping en el desarrollo ágil de software es muy propicio.

Ventajas Desventajas
Código más corto y eficiente. En parte, difícil de comprender para personas ajenas.
Realizable con métodos no conocidos en el momento de la programación. Basado en una forma de pensar no habitual en las personas (estado de solución).
Optimización sencilla, ya que la ejecución se gestiona mediante un algoritmo. Las características de casos de aplicación individuales se pueden considerar en la programación, pero únicamente de forma compleja.
Es posible el mantenimiento independiente del desarrollo de la aplicación.  

En la práctica, hoy en día se utilizan principalmente formas mixtas de paradigmas y los lenguajes de programación declarativa se complementan con métodos imperativos. Sin embargo, estas fórmulas son más propensas a contener errores y pueden perjudicar la legibilidad del código.