\documentclass{book}
\renewcommand{\chaptername}{Lecture}
\usepackage{amsmath}
\usepackage{ctable}
\usepackage[mathletters]{ucs}
\usepackage[utf8x]{inputenc}
% Redefine labelwidth for lists; otherwise, the enumerate package will cause
% markers to extend beyond the left margin.
\makeatletter\AtBeginDocument{%
  \renewcommand{\@listi}
    {\setlength{\labelwidth}{4em}}
}\makeatother
\usepackage{enumerate}
\usepackage[breaklinks=true,unicode=true]{hyperref}
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
%\setcounter{secnumdepth}{0}


\begin{document}

\setcounter{chapter}{18}

\chapter{Template Haskell based implementation of \texttt{printf}}

In the last lecture we saw a type class based solution to create
functions that take variable number of arguments. Here we give a
template haskell based solution.

\section{What is Template Haskell ?}

Template haskell is the Haskell way of doing Meta programming. At the
very least one can use it like a macro substitution but it can be used
to do much more. The idea is to process the Haskell code at compile time
using Haskell itself. A programmer can write Haskell functions to
manipulate Haskell code and using special syntax arrange the compiler to
manipulate code at compile time. In this lecture we will see how to
define a version of printf using template haskell.

Template Haskell consists of two important steps.

\begin{enumerate}[1.]
\item
  Quoting: To allow user defined function to manipulate the Haskell code
  one needs to represent the program as a value in some suitable data
  type. The data types defined in the module
  \texttt{Language.Haskell.TH.Syntax} is used for this purpose. For
  example the type \texttt{Exp} defined in the above module is used to
  represent a valid Haskell expression. Have a look into the
  documentation of that module.
\item
  Splicing. Once the Haskell language fragment is processed using
  various function defined by the user, it needs to be compiled by the
  compiler. This processing is called splicing.
\end{enumerate}
One point to be noted though is that template haskell does not splice
the code directly but only those that are expressions that are inside
the quoting monad Q. This monad is required because while generate code
various side effects are created. For example a variable \texttt{x} used
in a fragment of the code has a different meaning if there is a local
binding defined on it. Besides one would want to read in data from files
(think of config files) to perform compile time operations.

There are two syantactic extensions to Haskell that makes template
Haskell possible. If a haskell expression is written between
\texttt{{[}\textbar{}} and \texttt{\textbar{}{]}}, the compiler will
replace it with the corresponding representation in
\texttt{Language.Haskell.TH.Syntax}. For example, the expression
\texttt{{[}\textbar{} "Hello" \textbar{}{]}} is of type \texttt{Q Exp}.
The corresponding \texttt{Exp} value is \texttt{LitE (StringL "Hello")}.

The following are the extra syntactic conventions used.

\begin{enumerate}[1.]
\item
  \texttt{{[}e\textbar{} ... \textbar{}{]}} or just
  \texttt{{[}\textbar{}} \ldots{} `\textbar{}{]}' for quoting
  expressions. This has type \texttt{Q Exp}.
\item
  \texttt{{[}d\textbar{} ... \textbar{}{]}} for quoting declarations.
  This has type \texttt{Q {[}Decl{]}}
\item
  \texttt{{[}t\textbar{} ... \textbar{}{]}} for quoting types. This has
  type \texttt{Q Type}.
\item
  \texttt{{[}p\textbar{} ... \textbar{}{]}} for quoting patterns. This
  has type \texttt{Q Pat}.
\end{enumerate}
The splicing is done using the syntax \texttt{\$(...)} (no space between
\texttt{\$} and \texttt{(})

\section{Some convenience types and combinators}

The types \texttt{Q Exp} and \texttt{Q Pat} etc occur so often that
there are aliases for them \texttt{ExpQ} and \texttt{PatQ} respectively.
As an exercise guess the types aliases for \texttt{Q Type} and
\texttt{Q Decl}.

Whenever possible it is better to make use of the
\texttt{{[}\textbar{} ... \textbar{}{]}} notation to build quoted
expressions. However sometimes it is better to use the constructors of
\texttt{Exp} directly. Recall that we can splice only quoted
expressions, i.e values of type Q Expr (or equivalently ExpQ). Say you
have a quoted expressions \texttt{qe} and \texttt{qf} which correspondes
to the haskell expression \texttt{e} and \texttt{f} respectively. If one
wants to obtaine the quoted expression which correspondes to the
application of the function \texttt{f} on the expression \texttt{e}, we
would have to do something like the following

\begin{verbatim}

qfe = do e <- qe
         f <- qf
     return $ AppE f e.
\end{verbatim}
To make this efficient there is a combinator called \texttt{appE} which
does essentially what the constructor \texttt{AppE} does but works on
\texttt{Q Exp} rather than \texttt{Exp}.

\begin{verbatim}

appE :: ExpQ -> ExpQ -> ExpQ
\end{verbatim}
The above code will then look like \texttt{appE qe qf}. There are such
monadic version of all the constructors of \texttt{Exp} available. Make
use of it.

\section{Printf}

First note that we have enabled template Haskell using the compiler
pragma given above. It should be the very first line of your source
code. A unrecognised pragma is ignored by the compiler but sometimes a
warning is issued.

\begin{verbatim}

> {-# LANGUAGE TemplateHaskell    #-}
> module Printf where
> import Data.List
> import Language.Haskell.TH
\end{verbatim}
Few things about enabling the template haskell. Strictly speaking this
module does not need TemplateHaskell, rather it can be written without
using template Haskell. This is because all it does is define functions
that process objects of type \texttt{Expr} or \texttt{ExprQ}. I have
enabled it so as to write \texttt{appE {[}\textbar{}show\textbar{}{]}}
instead of the more complicated. \texttt{appE (varE 'show)}

First let us capture the formating via a data type

\begin{verbatim}

> data Format = L String    -- ^ literal string
>             | S           -- ^ %s
>             | G           -- ^ %g generic type
>             deriving Show
\end{verbatim}
We need a function that will parse a string and the give the
corresponding list for format. The exact details are not really of
interest as far as template haskell is concerned. See the end of the
file for an implementation.

\begin{verbatim}

> format :: String -> [Format]
\end{verbatim}
The printf function can then be defined as.

\begin{verbatim}

> printf  :: String -> ExpQ
> printfP :: [Format] -> ExpQ
> printf = printfP . format
\end{verbatim}
We would rather implement the prinfP function. Let the list of
formatting instructions be {[}f\_1,..,f\_n{]}, then we want
\texttt{prinfP {[}f\_1,...,f\_n{]}} when spliced to return the code.

\begin{verbatim}

\ x0  ... xm -> concat [e1,...,e_n]
\end{verbatim}
Here e\_i depends on the ith format instruction f\_i. If f\_i is a
literal then it will just be a literal string. Otherwise it would be an
appropriate variable. In our case it should be \texttt{xj} where
\texttt{j} is the number of \emph{non-literal}, i.e. \texttt{S} or
\texttt{G}, formating instructions to the left of e\_i. The number $m$
is the total number of \emph{non-literal} formatting instructions in the
list {[}f\_1,\ldots{},f\_n{]} and should be less than or equal to n.

Suppose we know the number of variables to the left of a format
instruction f\_i, how do we generate the expression e\_i ? The following
function does that

\begin{verbatim}

> toExpQ :: Int         -- ^ formatting instructions to the left
>        -> Format      -- ^ The current spec.
>        -> (Int,ExpQ)  -- ^ The total number of non-literal instruction
>               -- to the left and the resulting expression.
> toExpQ i   (L s) = (i,string s)
> toExpQ i   S     = (i+1,varExp i)
> toExpQ i   G     = (i+1,showE $ varExp i)
\end{verbatim}
Here we make use of the following helper Template haskell functions
which we have defined subsequently.

\begin{verbatim}

> string  :: String -> ExpQ  -- ^ quote the string
> showE   :: ExpQ   -> ExpQ  -- ^ quoted showing
> varExp  :: Int    -> ExpQ  -- ^ quoted variable xi
> varPat  :: Int    -> PatQ  -- ^ quoted pattern xi
\end{verbatim}
The printfP function then is simple. Recall that when spliced it should
generate the expression

\begin{verbatim}
       \ x0 ... xm -> concat [e1,...,e_n]`
\end{verbatim}
The complete definition is given below.

\begin{verbatim}

> printfP fmts = lamE args . appE conc $ listE es
>         where (nvars,es) = mapAccumL toExpQ 0 fmts
>               args       = map varPat [0 .. (nvars-1)]
>               conc       = [|concat|]
\end{verbatim}
Here are the definition of the helper functions

\begin{verbatim}

> string   = litE . StringL
> varExp i = varE $ mkName ("x" ++ show i)
> varPat i = varP $ mkName ("x" ++ show i)
> showE    = appE [|show|]
\end{verbatim}
We now come to the parsing of the format string. For simplicity of
implementation if \% occurs before an unknow format string it is treated
as literal occurance.

\begin{verbatim}

> format ""             = []
> format ['%']          = [L "%"]
> format ('%':x:xs)
>        | x == 's'  = S : format xs
>        | x == 'g'  = G : format xs
>        | x == '%'  = L "%" : format xs
>        | otherwise = L ['%',x] : format xs
> format zs          = L x : format xs
>        where (x,xs) = span (/='%') zs
\end{verbatim}
To try it out load it with ghci using the option -XTemplateHaskell. You
need this option to tell ghci that it better expect template haskell
stuff like Oxford bracket \texttt{{[}\textbar{} \textbar{}{]}} and
splicing \texttt{\$(...)}

\begin{verbatim}

$ ghci -XTemplateHaskell src/lectures/Template-Haskell-based-printf.lhs
GHCi, version 7.0.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Printf           ( src/lectures/Template-Haskell-based-printf.lhs, interpreted )
Ok, modules loaded: Printf.
*Printf> $(printf "%s is a string") "Hello"
"Hello is a string"
*Printf> $(printf "%s is a string %g is an int") "Hello" 10
"Hello is a string 10 is an int"
*Printf>
\end{verbatim}
\section{Exercise}

\begin{enumerate}[1.]
\item
  Write a function that will optimise the format instructions by merging
  consecutive literal strings. Is there any point in optimising the
  format instructions?
\item
  Rewrite the printf module to not use any template haskell itself.
\end{enumerate}

\end{document}
