jueves, julio 05, 2007

Estricto o Perezoso?

Pues si... desde hace poco ando trabajando en un proyectico de programación en Haskell, y no hago sino encontrarme inconvenientes :P.

Haskell es un lenguaje funcional llamado perezoso por la forma como evalúa las "expresiones" (diría funciones, pero así queda mas entendible para vírgenes mentes imperativas... como la mía).

La forma de evaluar perezosa básicamente implica que se comienza desde lo que está mas afuera:
Por ejemplo en C o C++ (o casi cualquier lenguaje imperativo) si escribimos...
F1(F2(argumento1),F3(argumento2)); 

El orden de evaluación sería F3, F2, F1 en cambio en un lenguaje perezoso (Lazy) se evaluan F1, F2, F3.

La pregunta obvia que surge es la siguiente...
Como voy a evaluar F1?? no tengo F2 y F3!!

Y la respuesta es sencilla... Los necesito o puedo seguir la ejecución? cuando los necesite los evalúo, sino guardo en memoria un recordatorio (hey acordate de evaluar F1 y F2)... usualmente al final ya toca evaluarlos, pero en los lenguajes funcionales muchas veces se suele reescribir y reescribir los terminos y yaaaa al final se evalúa.

Por ejemplo (sacado de estesitio)

La función:
foldr (+) 0 [1,2,3,4]

Va a operar con + todos los números (Partiendo del cero que se le pasa).

Lo interesante es ver como pospone la evaluación...
   1.  foldr (+) 0 [1,2,3,4]
2. 1 + foldr (+) 0 [2,3,4]
3. 1 + (2 + foldr (+) 0 [3,4])
4. 1 + (2 + (3 + foldr (+) 0 [4]))
5. 1 + (2 + (3 + (4 + foldr (+) 0 [])))
6. 1 + (2 + (3 + (4 + 0)))
7. 1 + (2 + (3 + (4 + 0)))
Y ahora...
Para que evaluación perezosa?

Hay muchas cosas bacanas (de hecho el link anterior tiene muchas), pero mi favorita es la posibilidad de manipular objetos infinitos.
take 5 [1..]

La lista [1..] es la lista de todos los enteros positivos (una lista por comprensión). Teniendo esto claro, la función anterior toma los primeros 5 elementos de los enteros positivos... con una evaluación estricta, se evaluarían inicialmente los parámetros, lo cual implicaría tiempo infinito, mientras que con evaluación perezosa evaluo solo lo que necesito.

El problema?

Pues lo que llame recordatorios ocupan memoria... y a veces todo el heap se va en recordatorios :S

Como Solucionarlo?
Dado que me extendí mucho eso lo dejo para el próximo post.

No hay comentarios.: