From: Matthijs Kooijman Date: Sat, 5 Dec 2009 23:32:21 +0000 (+0100) Subject: Various small fixes following from Bert's commentaar. X-Git-Tag: final-thesis~88 X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Freport.git;a=commitdiff_plain;h=19c17205efa182b80916caa31afeadad9d2dd5b5 Various small fixes following from Bert's commentaar. --- diff --git a/Chapters/Future.tex b/Chapters/Future.tex index 4eb297d..38d618f 100644 --- a/Chapters/Future.tex +++ b/Chapters/Future.tex @@ -47,13 +47,40 @@ will be desugared into: (somefunc a) >> (otherfunc b) \stophaskell -\todo{Properly introduce >>=} -There is also the \hs{>>=} operator, which allows for passing variables from -one expression to the next. If we could use this notation to compose a -stateful computation from a number of other stateful functions, this could -move all the boilerplate code into the \hs{>>} operator. Perhaps the compiler -should be taught to always inline the \hs{>>} operator, but after that there -should be no further changes required to the compiler. +The main reason to have the monadic notation, is to be able to wrap +results of functions in a datatype (the \emph{monad}) that can contain +extra information, and hide extra behaviour in the binding operators. + +The \hs{>>=} operator allows extracting the actual result of a function +and passing it to another function. Let's try to illustrate this from an +example. The following snippet: + +\starthaskell +do + x <- somefunc a + otherfunc x +\stophaskell + +will be desugared into: + +\starthaskell +(somefunc a) >>= (\\x -> otherfunc x) +\stophaskell + +The \hs{\\x -> ...} notation creates a lambda abstraction in Haskell, +that binds the \hs{x} variable. Here, the \hs{>>=} operator is supposed +to extract whatever result somefunc has and pass it to the lambda +expression created. This will probably not make the monadic notation +completely clear to a reader without prior experience with Haskell, but +it should serve to understand the following discussion. + +The monadic notation could perhaps be used to compose a number of +stateful functions into another stateful computation. Perhaps this could +move all the boilerplate code into the \hs{>>} and \hs{>>=} operators. +Because the boilerplate is still there (it's not magically disappeared, +just moved into these functions), the compiler should still be able to compile +these descriptions without any special magic (though perhaps it should +always inline the binding operators to reveal the flow of values). This is highlights an important aspect of using a functional language for our descriptions: We can use the language itself to provide abstractions of common diff --git a/Chapters/HardwareDescription.tex b/Chapters/HardwareDescription.tex index 24afd89..e5dab45 100644 --- a/Chapters/HardwareDescription.tex +++ b/Chapters/HardwareDescription.tex @@ -11,8 +11,8 @@ choices, we've tried to stick with the most obvious choice wherever possible. In a lot of cases, when you look at a hardware description it is comletely clear what hardware is described. We want our translator to - generate exactly that hardware whenever possible, to minimize the amount of - surprise for people working with it. + generate exactly that hardware whenever possible, to make working with Cλash + as intuitive as possible. In this chapter we try to describe how we interpret a Haskell program from a hardware perspective. We provide a description of each Haskell language @@ -129,8 +129,9 @@ and3 a b c = and (and a b) c \startbuffer[CaseInv] inv :: Bool -> Bool - inv True = False - inv False = True + inv x = case x of + True -> False + False -> True \stopbuffer \startuseMPgraphic{CaseInv} @@ -186,7 +187,7 @@ and3 a b c = and (and a b) c \placeexample[here][ex:PatternInv]{Simple inverter using pattern matching. Describes the same architecture as \in{example}[ex:CaseInv].} - {\typebufferhs{CaseInv}} + {\typebufferhs{PatternInv}} The architecture described by \in{example}[ex:PatternInv] is of course the same one as the one in \in{example}[ex:CaseInv]. The general interpretation @@ -296,7 +297,7 @@ and3 a b c = and (and a b) c To define an index for the 8 element vector above, we would do: \starthaskell - type Register = RangedWord D7 + type RegisterIndex = RangedWord D7 \stophaskell Here, a type synonym \hs{RegisterIndex} is defined that is equal to @@ -312,16 +313,20 @@ and3 a b c = and (and a b) c \subsection{User-defined types} There are three ways to define new types in Haskell: Algebraic datatypes with the \hs{data} keyword, type synonyms with the \hs{type} - keyword and type renamings with the \hs{newtype} keyword. This - explicitly excludes more advanced type creation from \GHC extensions - such as type families, existential typing, \small{GADT}s, etc. - - The first of these actually introduces a new type, for which we provide - the \VHDL translation below. The latter two only define new names for + keyword and type renamings with the \hs{newtype} keyword. \GHC + offers a few more advanced ways to introduce types (type families, + existential typing, \small{GADT}s, etc.) which are not standard + Haskell. These will be left outside the scope of this research. + + Only an algebraic datatype declaration actually introduces a + completely new type, for which we provide the \VHDL translation + below. Type synonyms and renamings only define new names for existing types (where synonyms are completely interchangeable and - renamings need explicit conversion). Therefore, these don't need any - particular \VHDL translation, a synonym or renamed type will just use - the same representation as the equivalent type. + renamings need explicit conversion). Therefore, these don't need + any particular \VHDL translation, a synonym or renamed type will + just use the same representation as the original type. The + distinction between a renaming and a synonym does no longer matter + in hardware and can be disregarded in the generated \VHDL. For algebraic types, we can make the following distinction: @@ -332,14 +337,15 @@ and3 a b c = and (and a b) c structure. In fact, the builtin tuple types are just algebraic product types (and are thus supported in exactly the same way). - The "product" in its name refers to the collection of values belonging + The \quote{product} in its name refers to the collection of values belonging to this type. The collection for a product type is the cartesian product of the collections for the types of its fields. - These types are translated to \VHDL, record types, with one field for + These types are translated to \VHDL record types, with one field for every field in the constructor. This translation applies to all single - constructor algebraic datatypes, including those with no fields (unit - types) and just one field (which are technically not a product). + constructor algebraic datatypes, including those with just one + field (which are technically not a product, but generate a VHDL + record for implementation simplicity). \stopdesc \startdesc{Enumerated types} \defref{enumerated types} @@ -361,6 +367,10 @@ and3 a b c = and (and a b) c for our purposes this distinction does not really make a difference, so we'll leave it out. + The \quote{sum} in its name refers again to the collection of values + belonging to this type. The collection for a sum type is the + union of the the collections for each of the constructors. + Sum types are currently not supported by the prototype, since there is no obvious \VHDL alternative. They can easily be emulated, however, as we will see from an example: @@ -754,7 +764,7 @@ acc in = out connected to one of the adder inputs). This notation has a number of downsides, amongst which are limited - readability and ambiguity in the interpretation. \note{Reference + readability and ambiguity in the interpretation. \todo{Reference Christiaan, who has done further investigation} \subsubsection{Explicit state arguments and results} diff --git a/Chapters/Prototype.tex b/Chapters/Prototype.tex index 40663f3..48c69b9 100644 --- a/Chapters/Prototype.tex +++ b/Chapters/Prototype.tex @@ -331,7 +331,7 @@ \startlambda λbndr.body \stoplambda - This is the basic lambda abstraction, as it occurs in labmda calculus. + This is the basic lambda abstraction, as it occurs in lambda calculus. It consists of a binder part and a body part. A lambda abstraction 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 diff --git a/Outline b/Outline index 3f1b8fd..75ed932 100644 --- a/Outline +++ b/Outline @@ -62,3 +62,6 @@ TODO: Say something about implementation differences with transformation specs TODO: Say something about the builtin functions somewhere (ref: christiaan) TODO: Reorder future work. TODO: Future work: Use Cλash +TODO: Abstract +TODO: Preface +TODO: strikethrough in pret-lam