Add a section on normalization of stateful descriptions.
[matthijs/master-project/report.git] / Chapters / Prototype.tex
index 257328e58d1da08923701176403ce0e06f5adb8d..139b93e56be69f2637efcffc785935e95bb77b9c 100644 (file)
     this does not concern the \emph{implementation language} of the compiler,
     just the language \emph{translated by} the compiler).
 
-    On the highest level, we have two choices:
+    Initially, we have two choices:
 
     \startitemize
       \item Create a new functional language from scratch. This has the
       advantage of having a language that contains exactly those elements that
       are convenient for describing hardware and can contain special
-      constructs that might.
+      constructs that allows our hardware descriptions to be more powerful or
+      concise.
       \item Use an existing language and create a new backend for it. This has
       the advantage that existing tools can be reused, which will speed up
       development.
     \stopitemize
 
+    \todo{Sidenote: No EDSL}
+
     Considering that we required a prototype which should be working quickly,
     and that implementing parsers, semantic checkers and especially
-    typcheckers isn't exactly the core of this research (but it is lots and
+    typcheckers is not exactly the core of this research (but it is lots and
     lots of work!), using an existing language is the obvious choice. This
     also has the advantage that a large set of language features is available
     to experiment with and it is easy to find which features apply well and
     just the useful features (and possibly extra features that are specific to
     the domain of hardware description as well).
 
-    The second choice is to pick one of the many existing languages. As
-    mentioned before, this language is Haskell.  This choice has not been the
+    The second choice is which of the many existing languages to use. As
+    mentioned before, the chosen language is Haskell.  This choice has not been the
     result of a thorough comparison of languages, for the simple reason that
     the requirements on the language were completely unclear at the start of
-    this language. The fact that Haskell is a language with a broad spectrum
+    this research. The fact that Haskell is a language with a broad spectrum
     of features, that it is commonly used in research projects and that the
-    primary compiler, GHC, provides a high level API to its internals, made
+    primary compiler, \GHC, provides a high level API to its internals, made
     Haskell an obvious choice.
 
-    TODO: Was Haskell really a good choice? Perhaps say this somewhere else?
+    \note{There should be evaluation of the choice of Haskell and \VHDL}
 
-  \subsection[sec:prototype:output]{Output format}
+  \section[sec:prototype:output]{Output format}
     The second important question is: What will be our output format? Since
     our prototype won't be able to program FPGA's directly, we'll have to have
     output our hardware in some format that can be later processed and
     However, \small{EDIF} is not completely tool-independent. It specifies a
     meta-format, but the hardware components that can be used vary between
     various tool and hardware vendors, as well as the interpretation of the
-    \small{EDIF} standard (TODO Is this still true? Reference:
-    http://delivery.acm.org/10.1145/80000/74534/p803-li.pdf?key1=74534\&key2=8370537521\&coll=GUIDE\&dl=GUIDE\&CFID=61207158\&CFTOKEN=61908473).
+    \small{EDIF} standard. \todo{Is this still true? Reference:
+    http://delivery.acm.org/10.1145/80000/74534/p803-li.pdf?key1=74534\&key2=8370537521\&coll=GUIDE\&dl=GUIDE\&CFID=61207158\&CFTOKEN=61908473}
    
-    This means that when working with EDIF, our prototype would become
+    This means that when working with \small{EDIF}, our prototype would become
     technology dependent (\eg only work with \small{FPGA}s of a specific
     vendor, or even only with specific chips). This limits the applicability
     of our prototype. Also, the tools we'd like to use for verifying,
     simulating and draw pretty pictures of our output (like Precision, or
-    QuestaSim) work on \small{VHDL} or Verilog input (TODO: Is this really
-    true?).
+    QuestaSim) are designed for \small{VHDL} or Verilog input.
 
-    For these reasons, we will use \small{VHDL} as our output language.
-    Verilog is not used simply because we are familiar with \small{VHDL}
-    already. The differences between \small{VHDL} and Verilog are on the
-    higher level, while we will be using \small{VHDL} mainly to write low
-    level, netlist-like descriptions anyway.
+    For these reasons, we will not use \small{EDIF}, but \small{VHDL} as our
+    output language.  We choose \VHDL over Verilog simply because we are
+    familiar with \small{VHDL} already. The differences between \small{VHDL}
+    and Verilog are on the higher level, while we will be using \small{VHDL}
+    mainly to write low level, netlist-like descriptions anyway.
 
     An added advantage of using VHDL is that we can profit from existing
     optimizations in VHDL synthesizers. A lot of optimizations are done on the
     Note that we will be using \small{VHDL} as our output language, but will
     not use its full expressive power. Our output will be limited to using
     simple, structural descriptions, without any behavioural descriptions
-    (which might not be supported by all tools).
+    (which might not be supported by all tools). This ensures that any tool
+    that works with \VHDL will understand our output (most tools don't support
+    synthesis of more complex \VHDL). This also leaves open the option to
+    switch to \small{EDIF} in the future, with minimal changes to the
+    prototype.
 
   \section{Prototype design}
-    As stated above, we will use the Glasgow Haskell Compiler (\small{GHC}) to
+    As suggested above, we will use the Glasgow Haskell Compiler (\small{GHC}) to
     implement our prototype compiler. To understand the design of the
     compiler, we will first dive into the \small{GHC} compiler a bit. It's
     compilation consists of the following steps (slightly simplified):
       % Create objects
       save inp, front, desugar, simpl, back, out;
       newEmptyBox.inp(0,0);
-      newBox.front(btex Parser etex);
+      newBox.front(btex Fronted etex);
       newBox.desugar(btex Desugarer etex);
       newBox.simpl(btex Simplifier etex);
       newBox.back(btex Backend etex);
       \emph{Core} language. Core is a very small functional language with lazy
       semantics, that can still express everything Haskell can express. Its
       simpleness makes Core very suitable for further simplification and
-      translation. Core is the language we will be working on as well.
+      translation. Core is the language we will be working with as well.
     \stopdesc
     \startdesc{Simplification}
       Through a number of simplification steps (such as inlining, common
     representation as well.
 
     However, we will use the normal core representation, not the simplified
-    core. Reasons for this are detailed below.
+    core. Reasons for this are detailed below. \todo{Ref}
     
     The final prototype roughly consists of three steps:
     
-    \startuseMPgraphic{ghc-pipeline}
+    \startuseMPgraphic{clash-pipeline}
       % Create objects
       save inp, front, norm, vhdl, out;
       newEmptyBox.inp(0,0);
       % Draw the objects (and deferred labels)
       drawObj (inp, front, norm, vhdl, out);
     \stopuseMPgraphic
-    \placefigure[right]{GHC compiler pipeline}{\useMPgraphic{ghc-pipeline}}
+    \placefigure[right]{Cλash compiler pipeline}{\useMPgraphic{clash-pipeline}}
 
     \startdesc{Frontend}
       This is exactly the frontend and desugarer from the \small{GHC}
     \in{chapter}[chap:normalization].
     
   \section{The Core language}
+    \defreftxt{core}{the Core language}
     Most of the prototype deals with handling the program in the Core
     language. In this section we will show what this language looks like and
     how it works.
     Each Core expression consists of one of these possible expressions.
 
     \startdesc{Variable reference}
-\startlambda
-a
-\stoplambda
-      This is a simple reference to a binder. It's written down as the
-      name of the binder that is being referred to, which should of course be
-      bound in a containing scope (including top level scope, so a reference
-      to a top level function is also a variable reference). Additionally,
-      constructors from algebraic datatypes also become variable references.
+      \defref{variable reference}
+      \startlambda
+      x :: T
+      \stoplambda
+      This is a reference to a binder. It's written down as the
+      name of the binder that is being referred to along with its type. The
+      binder name should of course be bound in a containing scope (including
+      top level scope, so a reference to a top level function is also a
+      variable reference). Additionally, constructors from algebraic datatypes
+      also become variable references.
 
       The value of this expression is the value bound to the given binder.
 
-      Each binder also carries around its type, but this is usually not shown
-      in the Core expressions. Occasionally, the type of an entire expression
-      or function is shown for clarity, but this is only informational. In
-      practice, the type of an expression is easily determined from the
-      structure of the expression and the types of the binders and occasional
-      cast expressions. This minimize the amount of bookkeeping needed to keep
-      the typing consistent.
+      Each binder also carries around its type (explicitly shown above), but
+      this is usually not shown in the Core expressions. Only when the type is
+      relevant (when a new binder is introduced, for example) will it be
+      shown. In other cases, the binder is either not relevant, or easily
+      derived from the context of the expression. \todo{Ref sidenote on type
+      annotations}
     \stopdesc
+
     \startdesc{Literal}
-\startlambda
-10
-\stoplambda
-      This is a simple literal. Only primitive types are supported, like
+      \defref{literal}
+      \startlambda
+      10
+      \stoplambda
+      This is a literal. Only primitive types are supported, like
       chars, strings, ints and doubles. The types of these literals are the
       \quote{primitive} versions, like \lam{Char\#} and \lam{Word\#}, not the
       normal Haskell versions (but there are builtin conversion functions).
     \stopdesc
+
     \startdesc{Application}
-\startlambda
-func arg
-\stoplambda
-      This is simple function application. Each application consists of two
+      \defref{application}
+      \startlambda
+      func arg
+      \stoplambda
+      This is function application. Each application consists of two
       parts: The function part and the argument part. Applications are used
       for normal function \quote{calls}, but also for applying type
       abstractions and data constructors.
@@ -302,13 +314,19 @@ func arg
       The value of an application is the value of the function part, with the
       first argument binder bound to the argument part.
     \stopdesc
+
     \startdesc{Lambda abstraction}
-\startlambda
-λbndr.body
-\stoplambda
+      \defref{lambda abstraction}
+      \startlambda
+      λbndr.body
+      \stoplambda
       This is the basic lambda abstraction, as it occurs in labmda calculus.
       It consists of a binder part and a body part.  A lambda abstraction
-      creates a function, that can be applied to an argument. 
+      creates a function, that can be applied to an argument. The binder is
+      usually a value binder, but it can also be a \emph{type binder} (or
+      \emph{type variable}). The latter case introduces a new polymorphic
+      variable, which can be used in types later on. See
+      \in{section}[sec:prototype:coretypes] for details.
      
       Note that the body of a lambda abstraction extends all the way to the
       end of the expression, or the closing bracket surrounding the lambda. In
@@ -318,10 +336,12 @@ func arg
       The value of an application is the value of the body part, with the
       binder bound to the value the entire lambda abstraction is applied to.
     \stopdesc
+
     \startdesc{Non-recursive let expression}
-\startlambda
-let bndr = value in body
-\stoplambda
+      \defref{let expression}
+      \startlambda
+      let bndr = value in body
+      \stoplambda
       A let expression allows you to bind a binder to some value, while
       evaluating to some other value (where that binder is in scope). This
       allows for sharing of subexpressions (you can use a binder twice) and
@@ -334,9 +354,9 @@ let bndr = value in body
       calculus, it is easily translated to a lambda abstraction. The let
       expression above would then become:
 
-\startlambda
-(λbndr.body) value
-\stoplambda
+      \startlambda
+      (λbndr.body) value
+      \stoplambda
 
       This notion might be useful for verifying certain properties on
       transformations, since a lot of verification work has been done on
@@ -345,158 +365,324 @@ let bndr = value in body
       The value of a let expression is the value of the body part, with the
       binder bound to the value. 
     \stopdesc
-    \startdesc{Recursive let expression}
-\startlambda
-letrec
-  bndr1 = value1
-  \vdots
-  bndrn = valuen
-in 
-  body
-\stoplambda
 
+    \startdesc{Recursive let expression}
+      \startlambda
+      letrec
+        bndr1 = value1
+        \vdots
+        bndrn = valuen
+      in 
+        body
+      \stoplambda
       This is the recursive version of the let expression. In \small{GHC}'s
       Core implementation, non-recursive and recursive lets are not so
       distinct as we present them here, but this provides a clearer overview.
       
       The main difference with the normal let expression is that each of the
       binders is in scope in each of the values, in addition to the body. This
-      allows for self-recursive definitions or mutually recursive definitions.
+      allows for self-recursive or mutually recursive definitions.
 
       It should also be possible to express a recursive let using normal
       lambda calculus, if we use the \emph{least fixed-point operator},
-      \lam{Y}.
+      \lam{Y}. This falls beyond the scope of this report, since it is not
+      needed for this research.
     \stopdesc
+
     \startdesc{Case expression}
-\startlambda
-  case scrut of bndr
-    DEFAULT -> defaultbody
-    C0 bndr0,0 ... bndr0,m -> body0
-    \vdots
-    Cn bndrn,0 ... bndrn,m -> bodyn
-\stoplambda
-
-TODO: Define WHNF
-
-    A case expression is the only way in Core to choose between values. A case
-    expression evaluates its scrutinee, which should have an algebraic
-    datatype, into weak head normal form (\small{WHNF}) and (optionally) binds
-    it to \lam{bndr}. It then chooses a body depending on the constructor of
-    its scrutinee. If none of the constructors match, the \lam{DEFAULT}
-    alternative is chosen. 
-    
-    Since we can only match the top level constructor, there can be no overlap
-    in the alternatives and thus order of alternatives is not relevant (though
-    the \lam{DEFAULT} alternative must appear first for implementation
-    efficiency).
-    
-    Any arguments to the constructor in the scrutinee are bound to each of the
-    binders after the constructor and are in scope only in the corresponding
-    body.
-
-    To support strictness, the scrutinee is always evaluated into WHNF, even
-    when there is only a \lam{DEFAULT} alternative. This allows a strict
-    function argument to be written like:
-
-\startlambda
-function (case argument of arg
-  DEFAULT -> arg)
-\stoplambda
-
-    This seems to be the only use for the extra binder to which the scrutinee
-    is bound. When not using strictness annotations (which is rather pointless
-    in hardware descriptions), \small{GHC} seems to never generate any code
-    making use of this binder. The current prototype does not handle it
-    either, which probably means that code using it would break.
-
-    Note that these case statements are less powerful than the full Haskell
-    case statements. In particular, they do not support complex patterns like
-    in Haskell. Only the constructor of an expression can be matched, complex
-    patterns are implemented using multiple nested case expressions.
-
-    Case statements are also used for unpacking of algebraic datatypes, even
-    when there is only a single constructor. For examples, to add the elements
-    of a tuple, the following Core is generated:
-
-\startlambda
-sum = λtuple.case tuple of
-  (,) a b -> a + b
-\stoplambda
-  
-    Here, there is only a single alternative (but no \lam{DEFAULT}
-    alternative, since the single alternative is already exhaustive). When
-    it's body is evaluated, the arguments to the tuple constructor \lam{(,)}
-    (\eg, the elements of the tuple) are bound to \lam{a} and \lam{b}.
-  \stopdesc
-  \startdesc{Cast expression}
-\startlambda
-body :: targettype
-\stoplambda
-    A cast expression allows you to change the type of an expression to an
-    equivalent type. Note that this is not meant to do any actual work, like
-    conversion of data from one format to another, or force a complete type
-    change. Instead, it is meant to change between different representations
-    of the same type, \eg switch between types that are provably equal (but
-    look different).
-    
-    In our hardware descriptions, we typically see casts to change between a
-    Haskell newtype and its contained type, since those are effectively
-    different representations of the same type.
-
-    More complex are types that are proven to be equal by the typechecker,
-    but look different at first glance. To ensure that, once the typechecker
-    has proven equality, this information sticks around, explicit casts are
-    added. In our notation we only write the target type, but in reality a
-    cast expressions carries around a \emph{coercion}, which can be seen as a
-    proof of equality. TODO: Example
-
-    The value of a cast is the value of its body, unchanged. The type of this
-    value is equal to the target type, not the type of its body.
-
-    Note that this syntax is also used sometimes to indicate that a particular
-    expression has a particular type, even when no cast expression is
-    involved. This is then purely informational, since the only elements that
-    are explicitely typed in the Core language are the binder references and
-    cast expressions, the types of all other elements are determined at
-    runtime.
-  \stopdesc
-  \startdesc{Note}
-
-    The Core language in \small{GHC} allows adding \emph{notes}, which serve
-    as hints to the inliner or add custom (string) annotations to a core
-    expression. These shouldn't be generated normally, so these are not
-    handled in any way in the prototype.
-  \stopdesc
-  \startdesc{Type}
-\startlambda
-@type
-\stoplambda
-    It is possibly to use a Core type as a Core expression. This is done to
-    allow for type abstractions and applications to be handled as normal
-    lambda abstractions and applications above. This means that a type
-    expression in Core can only ever occur in the argument position of an
-    application, and only if the type of the function that is applied to
-    expects a type as the first argument. This happens for all polymorphic
-    functions, for example, the \lam{fst} function:
-
-\startlambda
-fst :: \forall a. \forall b. (a, b) -> a
-fst = λtup.case tup of (,) a b -> a
-
-fstint :: (Int, Int) -> Int
-fstint = λa.λb.fst @Int @Int a b
-\stoplambda
+      \defref{case expression}
+      \startlambda
+        case scrutinee of bndr
+          DEFAULT -> defaultbody
+          C0 bndr0,0 ... bndr0,m -> body0
+          \vdots
+          Cn bndrn,0 ... bndrn,m -> bodyn
+      \stoplambda
+
+      \todo{Define WHNF}
+
+      A case expression is the only way in Core to choose between values. All
+      \hs{if} expressions and pattern matchings from the original Haskell
+      PRogram have been translated to case expressions by the desugarer. 
+      
+      A case expression evaluates its scrutinee, which should have an
+      algebraic datatype, into weak head normal form (\small{WHNF}) and
+      (optionally) binds it to \lam{bndr}. It then chooses a body depending on
+      the constructor of its scrutinee. If none of the constructors match, the
+      \lam{DEFAULT} alternative is chosen. A case expression must always be
+      exhaustive, \ie it must cover all possible constructors that the
+      scrutinee can have (if all of them are covered explicitly, the
+      \lam{DEFAULT} alternative can be left out).
+      
+      Since we can only match the top level constructor, there can be no overlap
+      in the alternatives and thus order of alternatives is not relevant (though
+      the \lam{DEFAULT} alternative must appear first for implementation
+      efficiency).
+      
+      Any arguments to the constructor in the scrutinee are bound to each of the
+      binders after the constructor and are in scope only in the corresponding
+      body.
+
+      To support strictness, the scrutinee is always evaluated into
+      \small{WHNF}, even when there is only a \lam{DEFAULT} alternative. This
+      allows aplication of the strict function \lam{f} to the argument \lam{a}
+      to be written like:
+
+      \startlambda
+      f (case a of arg DEFAULT -> arg)
+      \stoplambda
+
+      According to the \GHC documentation, this is the only use for the extra
+      binder to which the scrutinee is bound.  When not using strictness
+      annotations (which is rather pointless in hardware descriptions),
+      \small{GHC} seems to never generate any code making use of this binder.
+      In fact, \GHC has never been observed to generate code using this
+      binder, even when strictness was involved.  Nonetheless, the prototype
+      handles this binder as expected.
+
+      Note that these case statements are less powerful than the full Haskell
+      case statements. In particular, they do not support complex patterns like
+      in Haskell. Only the constructor of an expression can be matched,
+      complex patterns are implemented using multiple nested case expressions.
+
+      Case statements are also used for unpacking of algebraic datatypes, even
+      when there is only a single constructor. For examples, to add the elements
+      of a tuple, the following Core is generated:
+
+      \startlambda
+      sum = λtuple.case tuple of
+        (,) a b -> a + b
+      \stoplambda
     
-    The type of \lam{fst} has two universally quantified type variables. When
-    \lam{fst} is applied in \lam{fstint}, it is first applied to two types.
-    (which are substitued for \lam{a} and \lam{b} in the type of \lam{fst}, so
-    the type of \lam{fst} actual type of arguments and result can be found:
-    \lam{fst @Int @Int :: (Int, Int) -> Int}).
-  \stopdesc
+      Here, there is only a single alternative (but no \lam{DEFAULT}
+      alternative, since the single alternative is already exhaustive). When
+      it's body is evaluated, the arguments to the tuple constructor \lam{(,)}
+      (\eg, the elements of the tuple) are bound to \lam{a} and \lam{b}.
+    \stopdesc
+
+    \startdesc{Cast expression}
+      \defref{cast expression}
+      \startlambda
+      body ▶ targettype
+      \stoplambda
+      A cast expression allows you to change the type of an expression to an
+      equivalent type. Note that this is not meant to do any actual work, like
+      conversion of data from one format to another, or force a complete type
+      change. Instead, it is meant to change between different representations
+      of the same type, \eg switch between types that are provably equal (but
+      look different).
+      
+      In our hardware descriptions, we typically see casts to change between a
+      Haskell newtype and its contained type, since those are effectively
+      different types (so a cast is needed) with the same representation (but
+      no work is done by the cast).
+
+      More complex are types that are proven to be equal by the typechecker,
+      but look different at first glance. To ensure that, once the typechecker
+      has proven equality, this information sticks around, explicit casts are
+      added. In our notation we only write the target type, but in reality a
+      cast expressions carries around a \emph{coercion}, which can be seen as a
+      proof of equality. \todo{Example}
+
+      The value of a cast is the value of its body, unchanged. The type of this
+      value is equal to the target type, not the type of its body.
+
+      \todo{Move and update this paragraph}
+      Note that this syntax is also used sometimes to indicate that a particular
+      expression has a particular type, even when no cast expression is
+      involved. This is then purely informational, since the only elements that
+      are explicitely typed in the Core language are the binder references and
+      cast expressions, the types of all other elements are determined at
+      runtime.
+    \stopdesc
+
+    \startdesc{Note}
+      The Core language in \small{GHC} allows adding \emph{notes}, which serve
+      as hints to the inliner or add custom (string) annotations to a core
+      expression. These shouldn't be generated normally, so these are not
+      handled in any way in the prototype.
+    \stopdesc
+
+    \startdesc{Type}
+      \defref{type expression}
+      \startlambda
+      @type
+      \stoplambda
+      It is possibly to use a Core type as a Core expression. For the actual
+      types supported by Core, see \in{section}[sec:prototype:coretypes]. This
+      \quote{lifting} of a type into the value domain is done to allow for
+      type abstractions and applications to be handled as normal lambda
+      abstractions and applications above. This means that a type expression
+      in Core can only ever occur in the argument position of an application,
+      and only if the type of the function that is applied to expects a type
+      as the first argument. This happens for all polymorphic functions, for
+      example, the \lam{fst} function:
+
+      \startlambda
+      fst :: \forall a. \forall b. (a, b) -> a
+      fst = λtup.case tup of (,) a b -> a
+
+      fstint :: (Int, Int) -> Int
+      fstint = λa.λb.fst @Int @Int a b
+      \stoplambda
+          
+      The type of \lam{fst} has two universally quantified type variables. When
+      \lam{fst} is applied in \lam{fstint}, it is first applied to two types.
+      (which are substitued for \lam{a} and \lam{b} in the type of \lam{fst}, so
+      the type of \lam{fst} actual type of arguments and result can be found:
+      \lam{fst @Int @Int :: (Int, Int) -> Int}).
+    \stopdesc
+
+    \subsection[sec:prototype:coretypes]{Core type system}
+      Whereas the expression syntax of Core is very simple, its type system is
+      a bit more complicated. It turns out it is harder to \quote{desugar}
+      Haskell's complex type system into something more simple. Most of the
+      type system is thus very similar to that of Haskell.
+
+      We will slightly limit our view on Core's type system, since the more
+      complicated parts of it are only meant to support Haskell's (or rather,
+      \GHC's) type extensions, such as existential types, \small{GADT}s, type
+      families and other non-standard Haskell stuff which we don't (plan to)
+      support.
+
+      In Core, every expression is typed. The translation to Core happens
+      after the typechecker, so types in Core are always correct as well
+      (though you could of course construct invalidly typed expressions).
+
+      Any type in core is one of the following:
+
+      \startdesc{A type variable}
+        \startlambda
+        t
+        \stoplambda
+
+        This is a reference to a type defined elsewhere. This can either be a
+        polymorphic type (like the latter two \lam{t}'s in \lam{id :: \forall t.
+        t -> t}), or a type constructor (like \lam{Bool} in \lam{not :: Bool ->
+        Bool}). Like in Haskell, polymorphic type variables always
+        start with a lowercase letter, while type constructors always start
+        with an uppercase letter.
+
+        \todo{How to define (new) type constructors?}
+
+        A special case of a type constructor is the \emph{function type
+        constructor}, \lam{->}. This is a type constructor taking two arguments
+        (using application below). The function type constructor is commonly
+        written inline, so we write \lam{a -> b} when we really mean \lam{-> a
+        b}, the function type constructor applied to \lam{a} and \lam{b}.
+
+        Polymorphic type variables can only be defined by a lambda
+        abstraction, see the forall type below.
+      \stopdesc
 
-  TODO: Core type system
+      \startdesc{A type application}
+        \startlambda
+          Maybe Int
+        \stoplambda
+
+        This applies a some type to another type. This is particularly used to
+        apply type variables (type constructors) to their arguments.
+
+        As mentioned above, applications of some type constructors have
+        special notation. In particular, these are applications of the
+        \emph{function type constructor} and \emph{tuple type constructors}:
+        \startlambda
+          foo :: a -> b
+          foo' :: -> a b
+          bar :: (a, b, c)
+          bar' :: (,,) a b c
+        \stoplambda
+      \stopdesc
+
+      \startdesc{The forall type}
+        \startlambda
+          id :: \forall a. a -> a
+        \stoplambda
+        The forall type introduces polymorphism. It is the only way to
+        introduce new type variables, which are completely unconstrained (Any
+        possible type can be assigned to it). Constraints can be added later
+        using predicate types, see below.
+
+        A forall type is always (and only) introduced by a type lambda
+        expression. For example, the Core translation of the
+        id function is:
+        \startlambda
+          id = λa.λx.x
+        \stoplambda
+
+        Here, the type of the binder \lam{x} is \lam{a}, referring to the
+        binder in the topmost lambda.
+
+        When using a value with a forall type, the actual type
+        used must be applied first. For example haskell expression \hs{id
+        True} (the function \hs{id} appleid to the dataconstructor \hs{True})
+        translates to the following Core:
+
+        \startlambda
+        id @Bool True
+        \stoplambda
+
+        Here, id is first applied to the type to work with. Note that the type
+        then changes from \lam{id :: \forall a. a -> a} to \lam{id @Bool ::
+        Bool -> Bool}. Note that the type variable \lam{a} has been
+        substituted with the actual type.
+
+        In Haskell, forall types are usually not explicitly specified (The use
+        of a lowercase type variable implicitly introduces a forall type for
+        that variable). In fact, in standard Haskell there is no way to
+        explicitly specify forall types. Through a language extension, the
+        \hs{forall} keyword is available, but still optional for normal forall
+        types (it is needed for \emph{existentially quantified types}, which
+        Cλash does not support).
+      \stopdesc
+
+      \startdesc{Predicate type}
+        \startlambda
+          show :: \forall a. Show s ⇒ s → String
+        \stoplambda
+       
+        \todo{Sidenote: type classes?}
+
+        A predicate type introduces a constraint on a type variable introduced
+        by a forall type (or type lambda). In the example above, the type
+        variable \lam{a} can only contain types that are an \emph{instance} of
+        the \emph{type class} \lam{Show}. \refdef{type class}
+
+        There are other sorts of predicate types, used for the type families
+        extension, which we will not discuss here.
+
+        A predicate type is introduced by a lambda abstraction. Unlike with
+        the forall type, this is a value lambda abstraction, that must be
+        applied to a value. We call this value a \emph{dictionary}.
+
+        Without going into the implementation details, a dictionary can be
+        seen as a lookup table all the methods for a given (single) type class
+        instance. This means that all the dictionaries for the same type class
+        look the same (\eg contain methods with the same names). However,
+        dictionaries for different instances of the same class contain
+        different methods, of course.
+
+        A dictionary is introduced by \small{GHC} whenever it encounters an
+        instance declaration. This dictionary, as well as the binder
+        introduced by a lambda that introduces a dictionary, have the
+        predicate type as their type. These binders are usually named starting
+        with a \lam{\$}. Usually the name of the type concerned is not
+        reflected in the name of the dictionary, but the name of the type
+        class is. The Haskell expression \hs{show True} thus becomes:
+
+        \startlambda
+        show @Bool \$dShow True
+        \stoplambda
+      \stopdesc
 
+      Using this set of types, all types in basic Haskell can be represented.
+      
+      \todo{Overview of polymorphism with more examples (or move examples
+      here)}.
+        
   \section[sec:prototype:statetype]{State annotations in Haskell}
+      \fxnote{This entire section on state annotations should be reviewed}
+
       Ideal: Type synonyms, since there is no additional code overhead for
       packing and unpacking. Downside: there is no explicit conversion in Core
       either, so type synonyms tend to get lost in expressions (they can be
@@ -508,18 +694,20 @@ fstint = λa.λb.fst @Int @Int a b
       (un)packing substates. This will result in many nested State constructors
       in a nested state type. \eg: 
 
-  \starttyping
-  State (State Bit, State (State Word, Bit), Word)
-  \stoptyping
+      \starttyping
+      State (State Bit, State (State Word, Bit), Word)
+      \stoptyping
 
       Alternative: Provide different newtypes for input and output state. This
       makes the code even more explicit, and typechecking can find even more
       errors. However, this requires defining two type synomyms for each
       stateful function instead of just one. \eg:
-  \starttyping
-  type AccumStateIn = StateIn Bit
-  type AccumStateOut = StateOut Bit
-  \stoptyping
+
+      \starttyping
+      type AccumStateIn = StateIn Bit
+      type AccumStateOut = StateOut Bit
+      \stoptyping
+
       This also increases the possibility of having different input and output
       states. Checking for identical input and output state types is also
       harder, since each element in the state must be unpacked and compared
@@ -528,9 +716,9 @@ fstint = λa.λb.fst @Int @Int a b
       Alternative: Provide a type for the entire result type of a stateful
       function, not just the state part. \eg:
 
-  \starttyping
-  newtype Result state result = Result (state, result)
-  \stoptyping
+      \starttyping
+      newtype Result state result = Result (state, result)
+      \stoptyping
       
       This makes it easy to say "Any stateful function must return a
       \type{Result} type, without having to sort out result from state. However,
@@ -684,19 +872,19 @@ fstint = λa.λb.fst @Int @Int a b
       look at the whole, we can conclude the following:
 
       \startitemize
-      \item A state unpack operation should not generate any \small{VHDL}. The binder
-      to which the unpacked state is bound should still be declared, this signal
-      will become the register and will hold the current state.
-      \item A state pack operation should not generate any \small{VHDL}. The binder th
-      which the packed state is bound should not be declared. The binder that is
-      packed is the signal that will hold the new state.
-      \item Any values of a State type should not be translated to \small{VHDL}. In
-      particular, State elements should be removed from tuples (and other
-      datatypes) and arguments with a state type should not generate ports.
-      \item To make the state actually work, a simple \small{VHDL} proc should be
-      generated. This proc updates the state at every clockcycle, by assigning
-      the new state to the current state. This will be recognized by synthesis
-      tools as a register specification.
+        \item A state unpack operation should not generate any \small{VHDL}. The binder
+        to which the unpacked state is bound should still be declared, this signal
+        will become the register and will hold the current state.
+        \item A state pack operation should not generate any \small{VHDL}. The binder th
+        which the packed state is bound should not be declared. The binder that is
+        packed is the signal that will hold the new state.
+        \item Any values of a State type should not be translated to \small{VHDL}. In
+        particular, State elements should be removed from tuples (and other
+        datatypes) and arguments with a state type should not generate ports.
+        \item To make the state actually work, a simple \small{VHDL} proc should be
+        generated. This proc updates the state at every clockcycle, by assigning
+        the new state to the current state. This will be recognized by synthesis
+        tools as a register specification.
       \stopitemize
 
 
@@ -750,12 +938,6 @@ fstint = λa.λb.fst @Int @Int a b
       Implementation issues: state splitting, linking input to output state,
       checking usage constraints on state variables.
 
-        Implementation issues
-          \subsection[sec:prototype:separate]{Separate compilation}
-          - Simplified core?
+      \todo{Implementation issues: Separate compilation, simplified core.}
 
-  \section{Haskell language coverage and constraints}
-    Recursion
-    Builtin types
-    Custom types (Sum types, product types)
-    Function types / higher order expressions
+% vim: set sw=2 sts=2 expandtab: