Si buscamos en la wikipedia “lazy evaluation”, podemos encontrar este concepto como lazy evaluation o call-by-need. Los dos nombres le quedan muy bien pero personalmente opino que call-by-need explica mejor lo que sucede. Lazy evaluation permite que un bloque de código sea evaluado luego o mejor dicho sólo cuando se lo necesite, esto nos permite realizar código que tiene un rendimiento superior en ciertas situaciones.
Veamos un ejemplo, supongamos que tengo la función multiplicación
1 | mult(a, b) = a * a |
Si llamara a esta función con los parámetros 8 y 5+2 de forma tradicional o eager sucedería lo siguiente :
1 2 3 4 | mult(8, 5+2) mult(8,7) 8*8 64 |
Pero si ejecutamos el código de forma perezosa:
1 2 3 | mult(8, 5+2) 8 * 8 64 |
En este caso la ejecución perezosa fue más eficiente que la forma tradicional o eager.
Para poner otro ejemplo si tengo la función loop
1 | loop(x) = loop(x) |
Esta función nunca termina, veamos que pasa si ejecutamos mult(2, loop(2))
1 2 3 4 5 | mult(2, loop(2)) mult(2, loop(2)) mult(2, loop(2)) mult(2, loop(2)) ... hasta el infinito y más allá... |
Pero si ejecutamos de forma perezosa
1 2 3 | mult(2, loop(2)) 2 * 2 4 |
Termina y nos da el resultado.
Si piensan bien, los programadores c (y sus derivados) utilizamos dos funciones que son lazy por cuestiones de rendimiento. Los operadores and y or son diferentes pero trabajan de forma similar. Vamos a analizar el and. El and es un operador que si un parámetro es falso, retorna falso y si los dos son verdaderos devolverá verdadero. Como ustedes ya saben no necesita analizar los dos parámetros, si el primero es falso. De esta forma podemos hacer lo siguiente:
1 | (a != null && a.nombre == “Peperino”) |
Si a es nulo nunca ejecutara la expresión: a.nombre == “Peperino”
Scala es un lenguaje que se puede indicar que un parámetro sea manejado de forma perezosa, para esto se debe utilizar “=>” cuando se declara el parámetro. Vamos a hacer una función “and” en Scala:
1 | def and(x:Boolean, y: => Boolean) = if (x) y else x |
De esta forma si “x” es verdadero devolvemos “y” y si “x” es falso, ni siquiera ejecutamos “y”.
Podemos probarla con la función loop:
1 2 3 | def loop : Boolean = loop //> loop: => Boolean and(false, loop) //> res1: Boolean = false |
La evaluación perezosa proviene del paradigma funcional, es una característica de Haskell y otros lenguajes funcionales, pero también podemos usarla en lenguajes multiparadigma como Scala.
<!--
-->
Más información | wikipedia