I am trying to learn Haskell
, but i am stuck in understanding lazy evaluation
.
Can someone explain me lazy evaluation in detail and the output of the following 2 cases[with explaination] in relation to the below given
Pseudo Code:
x = keyboard input (5)
y = x + 3 (=8)
echo y (8)
x = keyboard input (2)
echo y
Case 1: Static binding, lazy evaluation
Case 2: Dynamic binding, lazy evaluation.
I need to know what will the last line (echo y
) is going to print...in the above 2 cases.
Haskell is a lazy language. It does not evaluate expressions until it absolutely must. This frequently allows our programs to save time by avoiding unnecessary computation, but they are at more of a risk to leak memory. There are ways of introducing strictness into our programs when we don't want lazy evaluation.
Haskell uses lazy evaluation for all functions. On the plus side, lazy evaluation never does more reduction steps than eager evaluation, and sometimes many fewer. On the minus side, lazy evaluation can use a lot more memory in some cases, and it can be difficult to predict its performance ahead of time.
In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed (non-strict evaluation) and which also avoids repeated evaluations (sharing).
An expression is evaluated by normal order (leftmost outermost redex first). To avoid unnecessary computation, normal order reduction chooses to apply the function rather than first evaluating the argument.
Sorry this is way too long but...
I'm afraid the answer is going to depend a lot on the meaning of the words...
First, here's that code in Haskell (which uses static binding and lazy evaluation):
readInt :: String -> Int
readInt = read
main = do
x <- fmap readInt getLine
let y = x + 3
print y
x <- fmap readInt getLine
print y
It prints 8
and 8
.
Now here's that code in R which uses lazy evaluation and what some people call dynamic binding:
delayedAssign('x', as.numeric(readLines(n=1)))
delayedAssign('y', x + 3)
print(y)
delayedAssign('x', as.numeric(readLines(n=1)))
print(y)
It prints 8
and 8
. Not so different!
Now in C++, which uses strict evaluation and static binding:
#include <iostream>
int main() {
int x;
std::cin >> x;
int y = x + 3;
std::cout << y << "\n";
std::cin >> x;
std::cout << y << "\n";
}
It prints 8
and 8
.
Now let me tell you what I think the point of the question actually was ;)
"lazy evaluation" can mean many different things. In Haskell it has a very particular meaning, which is that in nested expressions:
f (g (h x))
evaluation works as if f
gets evaluated before g (h x)
, ie evaluation
goes "outside -> in". Practically this means that if f
looks like
f x = 2
ie just throws away its argument, g (h x)
never gets evaluated.
But I think that that is not where the question was going with "lazy evaluation". The reason I think this is that:
+
always evaluates its arguments! +
is the same whether you're using lazy
evaluation or not.
The only computation that could actually be delayed is keyboard input
--
and that's not really computation, because it causes an action to occur;
that is, it reads from the user.
Haskell people would generally not call this "lazy evaluation" -- they would call it lazy (or deferred) execution.
So what would lazy execution mean for your question? It would mean that the
action keyboard input
gets delayed... until the value x
is really really
needed. It looks to me like that happens here:
echo y
because at that point you must show the user a value, and so you must know what x is! So what would happen with lazy execution and static binding?
x = keyboard input # nothing happens
y = x + 3 # still nothing happens!
echo y (8) # y becomes 8. 8 gets printed.
x = keyboard input (2) # nothing happens
echo y # y is still 8. 8 gets printed.
Now about this word "dynamic binding". It can mean different things:
Variable scope and lifetime is decided at run time. This is what languages like R do that don't declare variables.
The formula for a computation (like the formula for y
is x + 3
) isn't
inspected until the variable is evaluated.
My guess is that that is what "dynamic binding" means in your question. Going over the code again with dynamic binding (sense 2) and lazy execution:
x = keyboard input # nothing happens
y = x + 3 # still nothing happens!
echo y (8) # y becomes 8. 8 gets printed.
x = keyboard input (2) # nothing happens
echo y # y is already evaluated,
# so it uses the stored value and prints 8
I know of no language that would actually print 7
for the last line... but I
really think that's what the question was hoping would happen!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With