domingo, febrero 17, 2008

programación imperativa vs declarativa

Programación imperativa vs declarativa


Yo no soy expecialista en programación declarativa.

Una visión global y breve...



Conceptos breves antes de empezar...

La característica fundamental de la programación declarativa es que no tiene asignación destructiva. Es decir, que una variable no puede cambiar su valor.

Esto provoca que el orden de ejecución no tiene porque ser secuencial.

Los bucles hay que reemplazarlos por funciones recursivas.






1.---------------------------------------------------------------

Existen problemas que son naturalmente imperativos.
Un programa se descompone en entrada, proceso y salida.
Tanto la entrada como la salida, son acciones imperativas (consola, conexión tcp, fichero, etc..).

La mayoría de lenguajes declarativos, tienen características imperativas para ello (no son declarativos puros)




2.---------------------------------------------------------------

Todos los programadores declarativos conocen la programación imperativa.
Lógicamente, esto es porque la programación imperativa está muchísimo más extendida

Casi todos los programadores declarativos, empezaron con la programación imperativa, y ahora defienden la programación declarativa sobre la imperativa.

Esto podría ser el famoso efecto de las minorías y débiles, que tratan de compensarlo gritando más.
Pero en este caso, lo argumentan con lógica.

Richard Stallman, un genio de la programación, eligió LISP para su proyecto estrella Emacs

c omega es el lenguaje de programación para experimentar novedades para c#.
Inicialmente, este lenguaje se obtenía modificando el compilador de c# (que está escrito en c++ ¿no es tan bueno c#?).
Pero los programadores dijeron que era muy duro andar tocando el compilador c++ y optaron por utilizar un dialecto de scheme que generaba código c#, que luego volvían a compilar.

Aquí hay un tutorial de haskell para programadores imperativos
http://www.haskell.org/~pairwise/intro/intro.html






3.---------------------------------------------------------------

En la programación declarativa es más fácil la verificación de los programas.
En programación imperativa no sólo importa los valores con los que se llaman, también depende el orden de la llamada al método, a los métodos del objeto y casi siempre, a cualquier cosa del programa. Esto provoca una explosión de posibilidades imposible de verificar.





4.---------------------------------------------------------------

Los lenguajes declarativos suelen tener un poder expresivo impresionante.
El caso más radical es Haskell. Probablemente el lenguaje más potente y expresivo.

Quizá para ser capaz de sacarle partido, es necesaria una capacidad especial.





5.---------------------------------------------------------------

Los lenguajes declarativos, especialmente Haskell tienen fama de no ser muy eficientes.

Creo que para ejemplos sencillos, que se pueden optimizar fácilmente en c/c++ (por ejemplo), Haskell puede estar detrás.
Pero para casos reales, grandes y complejos de optimizar, Haskell tiene ventajas importantes.

La evaluación perezosa, la optimización dinámica y que el compilador pueda elegir el orden de ejecución para buscar el más óptimo... seguramente produzcan un código muy eficiente, sin mucha preocupación al programador.
Sin estas herramientas, todos sabemos, que las optimizaciones son la principal fuente de errores en los programas.






6.---------------------------------------------------------------

Los lenguajes declarativos son naturalmente paralelizables

Aquí la diferencia es radical e incomparable.
Un ejemplo muy bueno está en el lenguaje Erlang.

Erlang es un lenguaje declarativo muy, muy sencillo (uno de los más sencillos que he visto en mi vida)
Está orientado a sistemas de ejecución paralela, distribuida, tolerante a fallos, ejecución continua...

Para el SO, crear un proceso es caro, conmutar un proceso es caro.
Es más barato con hebras (para eso se crearon), pero aún así sigue siendo un recurso caro (unos pocos miles es demasiado).

En Erlang, crear un proceso es increíblemente barato, y lo mismo para las conmutaciones, y lo mismo para el paso de mensajes (nada de numeritos, mensajes complejos)

Ejemplo en yaws (yet another web server). Comparación con apache.
http://www.sics.se/~joe/apachevsyaws.html

Esta comparación es salvaje, pero también es comparar dos productos en el punto fuerte de uno de ellos.

En 4000 peticiones simultáneas, Apache casca, demasiados procesos.
Mientas que yaws (erlang) da mejor rendimiento incluso para 80.000 peticiones simultáneas.






7.---------------------------------------------------------------

El futuro es la programación paralela, dicen algunos.

La velocidad de los micros se ha parado, ahora buscan potencia haciéndolos multinúcleo.
Intel dice que prevee meter hasta 100 núcleos.

¿Están los programas preparados para aprovechar estas nuevas configuraciones?
NO
¿Están los lenguajes de programación preparados para ayudar en este nuevo escenario?
Los imperativos no.

Aquí tenéis un artículo fantástico
http://www.gotw.ca/publications/concurrency-ddj.htm




8.---------------------------------------------------------------

La programación declarativa es extrictamente académica??

Seguro que no está tan difundida como la imperativa, pero muchos defienden que no es puramente académica.

Se utilizar en las universidades, por profesores e investigadores, porque probablemente es la mejor opción.

Erlang está funcionando en máquinas muy caras con unas cifras espectaculares.
Ericson está explotando Erlang en máquinas con programas de más de 3 millones de líneas de código, con una tasa de fallo de 31 milisegundos al año
http://www.erlang.se/publications/BYTE2003.html





9.---------------------------------------------------------------

La programación declarativa es mejor para cosas pequeñas.

Erlang ha demostrado que puede funcionar muy bien en proyectos enormes.

Exprogramadores imperativos dicen que la gran ventaja de Haskell es para programas grandes o enormes
http://www.haskell.org/~pairwise/intro/intro.html

Scala recomienda utilizar todo lo posible la programación declarativa para poder eSCALAr al máximo.



10.-------------------------------------------------------------

Gran parte de las novedades de los lenguajes imperativos, o son características declarativas, o son cosas que aparecieron antes en estos lenguajes.



11.-------------------------------------------------------------

Líneas de código, tiempo de desarrollo...
Algunas pruebas dicen que Haskell gana
http://www.haskell.org/papers/NSWC/jfp.ps



12.-------------------------------------------------------------

Un inconveniente con los lenguajes muy expresivos, es que hace difícil la vida a los IDE y los compiladores.
Para un IDE es mucho más difícil funciones como autocompletar.
Para un compilador es más difícil informar con precisión del error.

Ver caso de C++ (seguro que también le sucederá a Scala). Creo que le pasa a Haskell

No hay comentarios: