Daniel Keast

Short circuiting is lazy

haskell, programming

I’m used to the concept of short circuiting operators. For example, in this Python code “evaluated” is never printed as it is clear before then that the entire if branch must resolve to True.

>>> if True or print("evaluated"):
...     print("inside")
...
inside

This is a special case though, in function calls the arguments are all evaluated and the results are passed in. For example, despite the second argument to the lambda f never being used, “evaluated” is still printed here.

>>> f = lambda x, y: print(x)
>>> f("inside", print("evaluated"))
evaluated
inside

The ‘||’ operator in Haskell short circuits as well, but is also just an ordinary function. It turns out the reason Haskell doesn’t need any special case for this is because of it’s lazy nature. Instead of evaluating all the arguments to a function and passing them in, Haskell passes in ‘thunks’ which will only be evaluated when necessary.

This is the example from Chapter 2 of real world haskell that’s made me realise this:

Prelude> newOr a b = if a then a else b
Prelude> newOr True (length [1..] > 0)
True

The second argument to newOr is attempting to calculate the length of an infinite list, but since the first argument is True it never gets evaluated.