\documentclass{beamer}
\usepackage{amsmath}
\usepackage{listings}
\usepackage{stmaryrd}

\title{Real World Haskell:\\
  Lecture 6}
\author{Bryan O'Sullivan}
\date{2009-11-11}

\begin{document}
\lstset{language=Haskell}

\frame{\titlepage}

\begin{frame}[fragile]
  \frametitle{Models of evaluation}
  
  Coming from a C++ or Python background, you're surely used to the
  the \lstinline{||} and \lstinline{or} operators in those languages.
  \begin{itemize}
  \item If the operator's left argument evaluates to true, it ``short
    circuits'' the right (i.e. doesn't evaluate it).
  \end{itemize}

  \vskip8pt We see the same behaviour in Haskell.
\begin{verbatim}
Prelude> undefined
*** Exception: Prelude.undefined

Prelude> True || undefined
True
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Eager, or strict, evaluation}
  
  In most languages, the usual model of is of \alert{strict
    evaluation}: a function's arguments are fully evaluated before the
  evaluation of the function's body begins.

\begin{verbatim}
def inc(x):
  return x + 1

def bar(a):
  b = 5 if a % 2 else 8
  return inc(a + 3) * inc(inc(b))
\end{verbatim}

  For example, if we run \texttt{bar(1)} then:
  \begin{itemize}
  \item The local variable \texttt{b} gets the value \texttt{5}.
  \item The two calls to \texttt{inc} are fully evaluated
    \emph{before} we invoke \texttt{*} on \texttt{5} and \texttt{7},
    respectively.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Are things different in Haskell?}
  
  Let's think about our old friend the list constructor.

\begin{verbatim}
Prelude> 1:[]
[1]
Prelude> 1:undefined
[1*** Exception: Prelude.undefined
\end{verbatim}

  And a function that operates on a list:
\begin{verbatim}
Prelude> head (1:[])      
1
\end{verbatim}

  What do you think will happen now?
  \pause
\begin{verbatim}
Prelude> head (1:undefined)
1
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Was that a special case?}
  
  Well, uh, perhaps lists are special in Haskell. Riiight?

\begin{lstlisting}
-- defined in Data.Maybe
isJust (Just _) = True
isJust _        = False
\end{lstlisting}

  Let's see how the \lstinline{Maybe} type fares.
\begin{verbatim}
Prelude Data.Maybe> Just undefined 
Just *** Exception: Prelude.undefined
Prelude Data.Maybe> isJust (Just undefined)
True
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
  \frametitle{What else should we expect?}
  
  Here's a slightly different function:
\begin{lstlisting}
isJustOne (Just a) | a == 1 = True
isJustOne _                 = False
\end{lstlisting}

  How will it behave?

\begin{verbatim}
*Main> isJustOne (Just 2)
False
\end{verbatim}

  Okay, we expected that. What if we follow the same pattern as
  before, and package up an \lstinline{undefined} value? \pause
\begin{verbatim}
*Main> isJustOne (Just undefined)
*** Exception: Prelude.undefined
\end{verbatim}
\end{frame}

\begin{frame}
  \frametitle{Haskell's evaluation model}
  
  Haskell follows a semantic model called \alert{non-strict
    evaluation}: expressions are not evaluated unless (and usually
  until) their values are used.

  \vskip8pt Perhaps you've heard of \alert{lazy evaluation}: this is a
  specific \emph{kind} of non-strict semantics.

  \vskip8pt Haskell compilers go further, using \alert{call by
    need} as an implementation strategy.

  \vskip8pt Call by need: evaluate an expression when needed, then
  \emph{overwrite} the location of the expression with the evaluated
  result (i.e.~memoize it), in case it is needed again.
\end{frame}

\begin{frame}[fragile]
  \frametitle{What does this mean in practice?}
  
  Consider the \lstinline{isJust} function again.
\begin{lstlisting}
isJust (Just _) = True
isJust _         = False
\end{lstlisting}

  It only evaluates its argument to the point of seeing whether it was
  constructed with a \lstinline{Just} or \lstinline{Nothing}
  constructor.

  \vskip8pt Notably, the function does \emph{not} inspect the argument
  of the \lstinline{Just} constructor.

  \vskip8pt When we try \lstinline{isJust (Just undefined)} in
  \texttt{ghci}, the value \lstinline{undefined} is never evaluated.
\end{frame}

\begin{frame}[fragile]
  \frametitle{And our other example, revisited}

  Who can explain why this code crashes when presented with
  \lstinline{Just undefined}?

\begin{lstlisting}
isJustOne (Just a) | a == 1 = True
isJustOne _                 = False
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{A classic example}
  
  Here is the infinite list of Fibonacci numbers in Haskell:

\begin{lstlisting}
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
\end{lstlisting}

  \vskip8pt Even though this list is conceptually infinite, its
  components only get generated on demand.

\begin{verbatim}
*Main> head (drop 256 fibs)
141693817714056513234709965875411919657707794958199867
\end{verbatim}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Traversing lists}
  
  What do these functions have in common? \vskip8pt

\begin{lstlisting}
map f []     = []
map f (x:xs) = f x : map f xs

bunzip []         = ([],[])
bunzip ((a,b):xs) = let (as,bs) = bunzip xs
                    in  (a:as,b:bs)
\end{lstlisting}
  \vskip8pt
\begin{verbatim}
*Main> map succ "button"
"cvuupo"
*Main> bunzip [(1,'a'),(3,'b'),(5,'c')]
([1,3,5],"abc")
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
  \frametitle{What does \lstinline{map} do?}
  
  If you think about what \lstinline{map} does to the \emph{structure}
  of a list, it replaces every \lstinline{(:)} constructor with a new
  \lstinline{(:)} constructor that has a transformed version of its
  arguments. \vskip8pt

\begin{lstlisting}
map succ (     1 :      2 : []) 
==       (succ 1 : succ 2 : [])
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{And \lstinline{bunzip}?}

  Thinking structurally, \lstinline{bunzip} performs the same kind of
  operation as \lstinline{map}. \vskip8pt

\begin{lstlisting}
bunzip ((1,'a') : (2,'b') : [])
==     ((1 : 2 : []), ('a' : 'b' : []))
\end{lstlisting}

  \vskip8pt This time, the pattern is much harder to see, but it's
  still there:
  \begin{itemize}
  \item Every time we see a \lstinline{(:)} constructor, we replace it
    with a transformed piece of data.
  \item In this case, the transformed data is the head pair pulled
    apart and grafted onto the heads of a pair of lists.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Abstraction! Abstraction! Abstraction!}
  
  If we have two functions that do essentially the same thing, don't
  we have a design pattern?

  \vskip8pt In Haskell, we can usually do better than waffle about
  design patterns: we can reify them into code!  To wit: \vskip8pt

\begin{lstlisting}
foldr f z []     = z
foldr f z (x:xs) = f x (foldr f z xs)
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{The right fold (no, really)}
  The \lstinline{foldr} function is called a \emph{right fold},
  because it associates to the right.  What do I mean by this?
  \vskip8pt

\begin{lstlisting}
   foldr (+) 1 [2,3,4] 
== foldr (+) 1 (2 :  3 :  4 : [])
== foldr (+) 1 (2 : (3 : (4 : [])))
==              2 + (3 + (4 + 1))
\end{lstlisting}

  \vskip8pt Notice a few things:
  \begin{itemize}
  \item We replaced the empty list with the ``empty'' value.
  \item We replaced each non-empty constructor with an addition
    operator.  
  \item That's our structural transformation in a nutshell!
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\lstinline{map} as a right fold}
  
  Because \lstinline{map} follows the same pattern as
  \lstinline{foldr}, we can actually write \lstinline{map} \emph{in
    terms of} \lstinline{foldr}! \vskip8pt

\begin{lstlisting}
bmap :: (a -> b) -> [a] -> [b]
bmap f xs = foldr g [] xs
    where g y ys = f y : ys
\end{lstlisting}

  \vskip8pt Since we can write a map as a fold, this implies that a
  fold is somehow \emph{more primitive than} a map.
\end{frame}

\begin{frame}[fragile]
  \frametitle{\lstinline{unzip} as a right fold}

  And here's our \lstinline{unzip}-like function as a fold: \vskip8pt
\begin{lstlisting}
bunzip :: [(a, b)] -> ([a], [b])
bunzip xs = foldr g ([],[]) xs
    where g (x,y) (xs,ys) = (x:xs, y:ys)
\end{lstlisting}

  \vskip8pt In fact, I'd suggest that
  \lstinline{bunzip}-in-terms-of-\lstinline{foldr} is actually
  \emph{easier} to understand than the original definition.

  \vskip8pt Many other common list functions can be expressed as right
  folds, too!
\end{frame}

\begin{frame}[fragile]
  \frametitle{Function composition (I)}
  
  Remember your high school algebra?

  \begin{align*}
    f\circ g\,(x) & \equiv f (g (x)) \\
    f \circ g & \equiv \lambda x \rightarrow f (g\, x)
  \end{align*}

  Taking the above notation and writing it in Haskell, we get this:

\begin{lstlisting}
f . g = \x -> f (g x)
\end{lstlisting}

  The backslash is Haskell ASCII art for $\lambda$, and introduces an
  \emph{anonymous} function.  Between the backslash and the ASCII
  arrow are the function's arguments, and following the arrow is its
  body.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Function composition (II)}

\begin{lstlisting}
f . g = \x -> f (g x)
\end{lstlisting}

  The result of \lstinline{f . g} is a function that accepts one
  argument, applied \lstinline{f} to it, then applies \lstinline{g} to
  the result.

  \vskip8pt So the expression \lstinline{succ . succ} adds two to a
  number, for instance.

  \vskip8pt Why care about this?  Well, here's our old definition of
  \lstinline{map}-as-\lstinline{foldr}.

\begin{lstlisting}
bmap f xs = foldr g [] xs
    where g y ys = f y : ys
\end{lstlisting}

  And here's a more succinct version.
\begin{lstlisting}
bmap f xs = foldr ((:) . f) [] xs
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{The left fold}
  
  So we've seen folds that associate to the right:
\begin{lstlisting}
1 + (2 + (3 + 4))
\end{lstlisting}
  \vskip8pt What about folds that associate to the left?
\begin{lstlisting}
((1 + 2) + 3) + 4
\end{lstlisting}

  \vskip8pt Not surprisingly, the left fold does indeed exist, and is
  named \lstinline{foldl}.
\begin{lstlisting}
foldl f z []     = z
foldl f z (x:xs) = foldl f (f z x) xs
\end{lstlisting}
\end{frame}

\begin{frame}
  \frametitle{The right fold in pictures}

  \begin{center}
    \includegraphics[height=2in]{6/foldr.png}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{The left fold in pictures}

  \begin{center}
    \includegraphics[height=0.9in]{6/foldl.png}
  \end{center}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Folds and laziness}
  
  Which of these definitions for adding up the elements of a list is
  better? \vskip8pt

\begin{lstlisting}
sum1 xs = foldr (+) 0 xs
sum2 xs = foldl (+) 0 xs
\end{lstlisting}

  \vskip8pt That's a hard question to approach without a sense of what
  lazy evaluation will cause to happen.

  \vskip8pt Suppose an oracle generates the list \lstinline{[1..1000]}
  for us at a rate of one element per second.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Sum as right fold}
  
  In the first second, we see the partial expression
\begin{lstlisting}
1 : (...) {- can't see anything more yet -}
\end{lstlisting}

  But we want to know the result as soon as possible, so we generate a
  partial result:

\begin{lstlisting}
1 + (...) {- can't make any more progress yet -}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Second number two}
  
  In the second second, we now have the partial expression
\begin{lstlisting}
1 : (2 : ...) {- can't see anything more yet -}
\end{lstlisting}

  \vskip8pt We thus construct a little more of our eventual result:

\begin{lstlisting}
1 + (2 + (...)) {- still no further progress -}
\end{lstlisting}
  
  \vskip8pt Because we're constructing a right-associative expression
  (that's what a right fold is \emph{for}), we can't create an
  intermediate result of the-sum-so-far at any point.

  \vskip8pt In other words, we're creating a big expression containing
  1000 nested applications of \lstinline{(+)}, which we'll only be
  able to fully evaluate at the end of the list!
\end{frame}

\begin{frame}[fragile]
  \frametitle{What happens in practice?}
  
  On casual inspection, it's not clear that this right fold business
  really matters.
\begin{verbatim}
Prelude> foldr (+) 0 [0..100000]
5000050000
\end{verbatim}

  \vskip8pt But if we try to sum a longer list, we get a problem:
\begin{verbatim}
Prelude> foldr (+) 0 [0..1000000]
*** Exception: stack overflow
\end{verbatim}

  \vskip8pt The GHC runtime imposes a limit on the size of a deferred
  expression to reduce the likelihood of us shooting ourselves in the
  foot.  Or at least to make the foot-shooting happen early enough
  that it won't be a serious problem.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Left folds are better \ldots\,uh, right?}
  
  Obviously, a left fold can't tell us the sum before we reach the end
  of a list, but it has a promising property.

  \vskip8pt Given a list like this:
\begin{lstlisting}
1 : 2 : 3 : ...
\end{lstlisting}

  \vskip8pt Then our \lstinline{sum}-via-\lstinline{foldl} will
  produce a result like this:
\begin{lstlisting}
((1 + 2) + 3) + ...
\end{lstlisting}

  \vskip8pt This is left associative, so we could potentially evaluate
  the leftmost portion on the fly: add \lstinline{1 + 2} to give 3,
  then add 3 to give 6, and so on, keeping a single \lstinline{Int} as
  the rolling sum-so-far.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Are we out of the woods?}
  
  So we know that this will fail:
\begin{verbatim}
Prelude> foldr (+) 0 [0..1000000]
*** Exception: stack overflow
\end{verbatim}

  \vskip8pt But what about this?
\begin{verbatim}
Prelude> foldl (+) 0 [0..1000000]
*** Exception: stack overflow
\end{verbatim}

  \vskip8pt \emph{Hey!} Shouldn't the left fold have saved our bacon?
\end{frame}

\begin{frame}[fragile]
  \frametitle{Why did \lstinline{foldl} not help?}
  
  Alas, consider the definition of \lstinline{foldl}:

\begin{lstlisting}
foldl :: (a -> b -> a) -> a -> [b] -> a
foldl f z []     = z
foldl f z (x:xs) = foldl f (f z x) xs
\end{lstlisting}

  \vskip8pt Because \lstinline{foldl} is polymorphic, there is no way
  it can inspect the result of \lstinline{f z x}.

  \vskip8pt And since the intermediate result of each
  \lstinline{f z x} can't be evaluated, a huge unevaluated expression
  piles up until we reach the end of the list, just as with
  \lstinline{foldr}!
\end{frame}

\begin{frame}[fragile]
  \frametitle{Tracing evaluation}
  
  How can we even get a sense of what pure Haskell code is actually
  doing? \vskip8pt
\begin{lstlisting}
import Debug.Trace

foldlT :: (Show a) => 
          (a -> b -> a) -> a -> [b] -> a
foldlT f z []     = z
foldlT f z (x:xs) = 
  let i = f z x
  in  trace ("now " ++ show i) foldlT f i xs
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{What does \lstinline{trace} do?}

  The \lstinline{trace} function is a magical function of sin: it
  prints its first argument on stderr, then returns its second
  argument.

  \vskip8pt The expression \lstinline{trace ("now " ++ show i) foldlT}
  prints something, then returns \lstinline{foldT}.

  \vskip8pt If you have the patience, run this in \texttt{ghci}:
\begin{verbatim}
Prelude> foldlT (+) 0 [0..1000000]
now 0
now 1
now 3
...blah blah blah...
500000500000
\end{verbatim}
  \emph{Whoa!} It eventually prints a result, where plain
  \lstinline{foldl} failed!
\end{frame}

\begin{frame}
  \frametitle{What's going on?}
  
  \begin{itemize}
  \item In order to print an intermediate result, \lstinline{trace}
    must evaluate it first.
  \item Haskell's call-by-need evaluation ensures that an unevaluated
    expression will be overwritten with the evaluated result.
  \item Instead of a constantly-growing expression, we thus have a
    single primitive value as the running sum at each iteration
    through the loop.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Is a debugging hack the answer to our problem?}
  
  Clearly, using \lstinline{trace} seems like an incredibly lame
  solution to the problem of evaluating intermediate results, although
  it's very useful for debugging.

  \vskip8pt (Actually, it's the only Haskell debugger I use.)

  \vskip8pt The \emph{real} solution to our problem lies in a function
  named \lstinline{seq}.
\begin{lstlisting}
seq :: a -> t -> t
\end{lstlisting}

  \vskip8pt This function is a rather magical hack; all it does is
  evaluate its first argument until it reaches a constructor, then
  return its second argument.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Folding with \lstinline{seq}}
  
  The \lstinline{Data.List} module defines the following function for
  us: \vskip8pt

\begin{lstlisting}
foldl' :: (a -> b -> a) -> a -> [b] -> a
foldl' f z []     = z
foldl' f z (x:xs) = let i = f z x
                    in  i `seq` foldl' f i xs
\end{lstlisting}

  \vskip8pt Let's compare the two in practice: \vskip8pt
\begin{verbatim}
Prelude> foldl (+) 0 [0..1000000]
*** Exception: stack overflow

Prelude> import Data.List
Prelude> foldl' (+) 0 [0..1000000]
500000500000
\end{verbatim}
\end{frame}

\begin{frame}
  \frametitle{Rules of thumb for folds}
  
  If you can generate your result lazily and incrementally, e.g.~as
  \lstinline{map} does, use \lstinline{foldr}.

  \vskip8pt If you are generating what is conceptually a single result
  (e.g. one number), use \lstinline{foldl'}, because it will evaluate
  those tricky intermediate results strictly.

  \vskip8pt Never use plain old \lstinline{foldl} without the little
  tick at the end.
\end{frame}

\begin{frame}
  \frametitle{Homework}
  
  For each of the following, choose the appropriate fold for the kind
  of result you are returning.  You can find the type signature for
  each function using \texttt{ghci}.
  \begin{itemize}
  \item Write \lstinline{concat} using a fold.
  \item Write \lstinline{length} using a fold.
  \item Write \lstinline{(++)} using a fold.
  \item Write \lstinline{and} using a fold.
  \item Write \lstinline{unwords} using a fold.
  \item Write \lstinline{(\\\\)} from Data.List using a fold.
  \end{itemize}

  \vskip8pt For super duper bonus points:
  \begin{itemize}
  \item Write either \lstinline{foldr} or \lstinline{foldl} in terms
    of the other.  (Hint 1: only one is actually possible.  Hint 2: the
    answer is highly non-obvious, and involves higher order
    functions.)
  \end{itemize}
\end{frame}
\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% TeX-PDF-mode: t
%%% End: 

