[convert the old 'jhc.txt' to markdown format and link to it off of the main page.
John Meacham <john@repetae.net>**20080210020142] move ./docs/jhc.txt ./docs/jhc.mkd
hunk ./Makefile.am 202
-publish: docs/building.shtml docs/big-picture.pdf docs/development.shtml docs/index.shtml
+publish: docs/building.shtml docs/big-picture.pdf docs/development.shtml docs/index.shtml docs/jhc.shtml
hunk ./docs/index.mkd 9
-See the [Installation page](building.shtml) for information about
+See the [Installation page](building.shtml) for information about downloading and installing jhc.
hunk ./docs/index.mkd 11
-Development
------------
+Development and other info
+--------------------------
hunk ./docs/index.mkd 14
-For information on getting and building the development tree of jhc, see
-[the development page](development.shtml). The
-[darcs repository](http://repetae.net/repos/jhc) may be browsed
-[with the darcsweb repository browser](http://repetae.net/dw/darcsweb.cgi?r=jhc).
-
-An informal graph of the internal code motion in jhc is [here (pdf)](big-picture.pdf).
+ * [The Orignal Page](jhc.shtml) is the somewhat modified original information page on jhc. lots of good stuff, some of it out of date.
+ * [the development page](development.shtml) has information on how to pull the development tree from the darcs repository
+ * the [darcs repository](http://repetae.net/repos/jhc) is where the code is housed
+ * [the darcsweb repository browser](http://repetae.net/dw/darcsweb.cgi?r=jhc) can be used to see a changelog and view individual patches
+ * An informal graph of the internal code motion in jhc is [here (pdf)](big-picture.pdf).
hunk ./docs/jhc.mkd 1
-= Jhc =
+Jhc
+===
hunk ./docs/jhc.mkd 16
-== Jhc Bullet Points ==
+Jhc Bullet Points
+-----------------
hunk ./docs/jhc.mkd 19
-* Full support for Haskell 98, The FFI and some extensions. (modulo some bugs
-being worked on and some libraries that need to be filled out)
+ * Full support for Haskell 98, The FFI and some extensions. (modulo some bugs
+   being worked on and some libraries that need to be filled out)
hunk ./docs/jhc.mkd 22
-* Produces 100% portable ISO C. The same C file can compile on machines of
-different byte order or bit-width without trouble.
+ * Produces 100% portable ISO C. The same C file can compile on machines of
+   different byte order or bit-width without trouble.
hunk ./docs/jhc.mkd 25
-* No pre-written runtime. other than 20 lines of boilerplate all code is generated from
-the Grin intermediate code and subject to all code simplifying and dead code
-elimination transformations. As a result, jhc currently produces the smallest binaries of
-any Haskell compiler. (main = putStrLn "Hello, World!" compiles to
-6,568 bytes vs 177,120 bytes for GHC 6.4)
+ * No pre-written runtime. other than 20 lines of boilerplate all code is generated from
+   the Grin intermediate code and subject to all code simplifying and dead code
+   elimination transformations. As a result, jhc currently produces the smallest binaries of
+   any Haskell compiler. (main = putStrLn "Hello, World!" compiles to
+   6,568 bytes vs 177,120 bytes for GHC 6.4)
hunk ./docs/jhc.mkd 31
-* No garbage collector. A variant of Region Inference is in the works.
+ * No garbage collector. A variant of Region Inference is in the works.
hunk ./docs/jhc.mkd 33
-* Compilation by transformation with 2 general intermediate languages.
+ * Compilation by transformation with 2 general intermediate languages.
hunk ./docs/jhc.mkd 35
-* First Intermediate language based on Henk, Pure Type Systems and the Lambda
-cube. This is similar enough to GHCs core that many optimizations may be
-implemented in the same way.
+ * First Intermediate language based on Henk, Pure Type Systems and the Lambda
+   cube. This is similar enough to GHCs core that many optimizations may be
+   implemented in the same way.
hunk ./docs/jhc.mkd 39
-* Second Intermediate language is based on Boquist's graph reduction language.
-This allows all unknown jumps to be compiled out leaving standard case
-statements and function calls as the only form of flow control. Combined with
-jhc's use of region inference, this means jhc can compile to most any standard
-imperative architecture/language/virtual machine directly without special
-support for a stack or tail-calls.
+ * Second Intermediate language is based on Boquist's graph reduction language.
+   This allows all unknown jumps to be compiled out leaving standard case
+   statements and function calls as the only form of flow control. Combined with
+   jhc's use of region inference, this means jhc can compile to most any standard
+   imperative architecture/language/virtual machine directly without special
+   support for a stack or tail-calls.
hunk ./docs/jhc.mkd 46
-* Novel type class implementation not based on dictionary passing with many
-attractive properties. This implementation is possible due to the
-whole-program analysis phase and the use of the lambda-cube rather than System
-F as the base for the functional intermediate language.
+ * Novel type class implementation not based on dictionary passing with many
+   attractive properties. This implementation is possible due to the
+   whole-program analysis phase and the use of the lambda-cube rather than System
+   F as the base for the functional intermediate language.
hunk ./docs/jhc.mkd 51
-* Intermediate language and back-end suitable for directly compiling any language that can
-be embedded in the full lambda cube, making things like a compiler for
-cayenne much more direct. There is no type erasure phase, types are erased for
-the simple reason that values do not depend on them via the standard dead-code
-elimination pass.
+ * Intermediate language and back-end suitable for directly compiling any language that can
+   be embedded in the full lambda cube, making things like a compiler for
+   cayenne much more direct. There is no type erasure phase, types are erased for
+   the simple reason that values do not depend on them via the standard dead-code
+   elimination pass.
hunk ./docs/jhc.mkd 57
-* A very modern design, it using rank-n polymorphism, monad transformers, generic
-programing, and existential types to make the code very concise and clear
-and improve code reuseability. (since jhc was written in pieces over 5 years, some at
-times when I just started using Haskell, the code quality actually varies a
-lot across the whole project)
+ * A very modern design, it using rank-n polymorphism, monad transformers, generic
+   programing, and existential types to make the code very concise and clear
+   and improve code reuseability. (since jhc was written in pieces over 5 years, some at
+   times when I just started using Haskell, the code quality actually varies a
+   lot across the whole project)
hunk ./docs/jhc.mkd 63
-* All indirect jumps are transformed away, jhc's final code is very similar to
-hand-written imperative code, using only branches and static function calls. A
-simple basic-blocks analysis is enough to transform tail-calls into loops.
+ * All indirect jumps are transformed away, jhc's final code is very similar to
+   hand-written imperative code, using only branches and static function calls. A
+   simple basic-blocks analysis is enough to transform tail-calls into loops.
hunk ./docs/jhc.mkd 67
-* Full transparent support for mutually recursive modules.
+ * Full transparent support for mutually recursive modules.
hunk ./docs/jhc.mkd 69
-== More in depth ==
+More in depth
+=============
hunk ./docs/jhc.mkd 73
-=== Type Classes ===
+Type Classes
+------------
hunk ./docs/jhc.mkd 88
-* The number of extra hidden parameters is the number of free type variables
-in a functions signature rather than the number of class constraints. So (Ord
-a, Show a, Num a) => a -> a will only pass a single extra parameter for the
-type of a rather than 3 dictionaries.
+ * The number of extra hidden parameters is the number of free type variables
+   in a functions signature rather than the number of class constraints. So (Ord
+   a, Show a, Num a) => a -> a will only pass a single extra parameter for the
+   type of a rather than 3 dictionaries.
hunk ./docs/jhc.mkd 93
-* 2 indirections, first one to look up the dictionary, then one to call the
-function pointed to in the dictionary are replaced by a single case of an
-algebraic data type and calls to statically known functions. This is exactly
-the transformation that the GRIN points-to analysis does, but much sooner and
-with much better optimization potential. Calls to statically known functions
-are MUCH more efficient.
+ * 2 indirections, first one to look up the dictionary, then one to call the
+   function pointed to in the dictionary are replaced by a single case of an
+   algebraic data type and calls to statically known functions. This is exactly
+   the transformation that the GRIN points-to analysis does, but much sooner and
+   with much better optimization potential. Calls to statically known functions
+   are MUCH more efficient.
hunk ./docs/jhc.mkd 100
-* Standard case coalescing optimizations have a dramatically enhanced effect
-when dealing with overloaded functions. imagine the code snipped (x*(y + z)/z) :: a .
-Each of the calls to the polymorphic functions *, +, and / will expand
-to a case statement on 'a', since all case statements are trivially examining
-the same value, they are coalesced into a single one. With dictionary passing,
-we would have to look up the appropriate entry in the Num hidden parameter,
-the Floating hidden parameter, then look up each of *, +, and / individually.
-Under jhc's scheme all of that is statically  transformed into a single case
-on a normal algebraic type. This optimization is a HUGE win.  Jhc's ability to
-do this comes from the fact that it is  statically evident from that case
-statement that the type fully determines every polymorphic function on that
-type, a property that is lost in the dictionary passing approach since as far
-as the compiler is concerned, arbitrary functions may be being passed in the
-dictionaries, it does not know that they come in specific correlated sets.
+ * Standard case coalescing optimizations have a dramatically enhanced effect
+   when dealing with overloaded functions. imagine the code snipped $(x*(y + z)/z) :: a$ .
+   Each of the calls to the polymorphic functions \*, +, and / will expand
+   to a case statement on 'a', since all case statements are trivially examining
+   the same value, they are coalesced into a single one. With dictionary passing,
+   we would have to look up the appropriate entry in the Num hidden parameter,
+   the Floating hidden parameter, then look up each of \*, +, and / individually.
+   Under jhc's scheme all of that is statically  transformed into a single case
+   on a normal algebraic type. This optimization is a HUGE win.  Jhc's ability to
+   do this comes from the fact that it is  statically evident from that case
+   statement that the type fully determines every polymorphic function on that
+   type, a property that is lost in the dictionary passing approach since as far
+   as the compiler is concerned, arbitrary functions may be being passed in the
+   dictionaries, it does not know that they come in specific correlated sets.
hunk ./docs/jhc.mkd 115
-* Functional Dependencies actually lead to run-time savings. each functional
-dependency transforms into a case statement which may be omitted.
+ * Functional Dependencies actually lead to run-time savings. each functional
+   dependency transforms into a case statement which may be omitted.
hunk ./docs/jhc.mkd 118
-* Although a whole-world analysis is needed to generate full versions of
-type class methods, this is actually rarely needed in practice, as it is often
-the case the compiler is able to statically prove only a certain subset of
-types are needed at any given point and is able to generate specialized
-versions on the spot. This is implemented in a manner very similar to GHC's
-rules.
+ * Although a whole-world analysis is needed to generate full versions of
+   type class methods, this is actually rarely needed in practice, as it is often
+   the case the compiler is able to statically prove only a certain subset of
+   types are needed at any given point and is able to generate specialized
+   versions on the spot. This is implemented in a manner very similar to GHC's
+   rules.
hunk ./docs/jhc.mkd 125
-* Advanced compile-time and run-time specializations are possible via pragmas.
-(see below)
+ * Advanced compile-time and run-time specializations are possible via pragmas.
+   (see below)
hunk ./docs/jhc.mkd 129
-=== E ===
+E
+-
hunk ./docs/jhc.mkd 136
-=== Grin ===
+Grin
+----
hunk ./docs/jhc.mkd 143
-* It is typed.
+ * It is typed.
hunk ./docs/jhc.mkd 145
-* It has multiple return values as a primitive (unboxed tuples)
+ * It has multiple return values as a primitive (unboxed tuples)
hunk ./docs/jhc.mkd 147
-* My target is higher level C or C-- rather than RISC code, so some
-transformations are less important as the C compiler can be assumed to take
-care of them.
+ * My target is higher level C or C-- rather than RISC code, so some
+   transformations are less important as the C compiler can be assumed to take
+   care of them.
hunk ./docs/jhc.mkd 151
-* The terminology and syntax borrows from Haskell's current implementation of
-monads and 'do' notation.
+ * The terminology and syntax borrows from Haskell's current implementation of
+   monads and 'do' notation.
hunk ./docs/jhc.mkd 162
- infixr 1  :->, :>>=
+    infixr 1  :->, :>>=
hunk ./docs/jhc.mkd 164
- data Lam = Val :-> Exp
-    deriving(Eq,Ord,Show)
+    data Lam = Val :-> Exp
+       deriving(Eq,Ord,Show)
hunk ./docs/jhc.mkd 167
- data Exp =
-     Exp :>>= !Lam
-    | App Atom [Val]  -- ^ this handles applications of functions and built-ins
-    | Prim Primitive [Val]
-    | Case Val [Lam]
-    | Return { expValue :: Val }
-    | Store { expValue :: Val }
-    | Fetch { expAddress :: Val }
-    | Update { expAddress :: Val, expValue :: Val }
-    | Error String Ty -- ^ abort with an error message, non recoverably.
-    | Cast Val Ty     -- ^ reinterpret Val as a different type, also used to box\/unbox lifted types
-    deriving(Eq,Show,Ord)
+    data Exp =
+        Exp :>>= !Lam
+       | App Atom [Val]  -- ^ this handles applications of functions and built-ins
+       | Prim Primitive [Val]
+       | Case Val [Lam]
+       | Return { expValue :: Val }
+       | Store { expValue :: Val }
+       | Fetch { expAddress :: Val }
+       | Update { expAddress :: Val, expValue :: Val }
+       | Error String Ty -- ^ abort with an error message, non recoverably.
+       | Cast Val Ty     -- ^ reinterpret Val as a different type, also used to box\/unbox lifted types
+       deriving(Eq,Show,Ord)
hunk ./docs/jhc.mkd 180
- data Val =
-    NodeC !Tag [Val]
-    | NodeV !Var [Val]
-    | Tag !Tag
-    | Const Val         -- ^ pointer to constant data, only Lit, Tag, and NodeC may be children
-    | Lit !Number Ty
-    | Var !Var Ty
-    | Tup [Val]
-    | ValPrim APrim
-    deriving(Eq,Show,Ord)
+    data Val =
+       NodeC !Tag [Val]
+       | NodeV !Var [Val]
+       | Tag !Tag
+       | Const Val         -- ^ pointer to constant data, only Lit, Tag, and NodeC may be children
+       | Lit !Number Ty
+       | Var !Var Ty
+       | Tup [Val]
+       | ValPrim APrim
+       deriving(Eq,Show,Ord)
hunk ./docs/jhc.mkd 191
- data Ty =
-    TyTag           -- ^ a lone tag
-    | TyPtr Ty      -- ^ pointer to a heap location which contains its argument
-    | TyNode        -- ^ a whole tagged node
-    | Ty Atom       -- ^ a basic type
-    | TyTup [Ty]    -- ^ unboxed list of values
-    | TyUnknown     -- ^ an unknown possibly undefined type, All of these must be eliminated by code generation
-    deriving(Eq,Ord)
+    data Ty =
+       TyTag           -- ^ a lone tag
+       | TyPtr Ty      -- ^ pointer to a heap location which contains its argument
+       | TyNode        -- ^ a whole tagged node
+       | Ty Atom       -- ^ a basic type
+       | TyTup [Ty]    -- ^ unboxed list of values
+       | TyUnknown     -- ^ an unknown possibly undefined type, All of these must be eliminated by code generation
+       deriving(Eq,Ord)
hunk ./docs/jhc.mkd 202
-=== Extensions ===
+Extensions
+----------
+
hunk ./docs/jhc.mkd 208
-==== Standard Extensions ====
+Standard Extensions
+-------------------
hunk ./docs/jhc.mkd 228
-==== New Extensions ====
-
-* Magic underscore. Using underscore in an expression expands to bottom with an error
-  message giving the current file and line number. This is useful because it
-  is common practice nowadays to use undefined as a witness for a type.
-  Relatively easy errors to make using this scheme lead to an unhelpful
-  "error: Prelude.undefined" with no indication of where the error actually is. By using the alternate <code>(_ :: Int)</code> rather than
-  <code>(undefined :: Int)</code> you will get an informative run-time error message as
-  well as save some space. The magic underscore is also useful as a
-  placeholder for code you mean to fill in later.
+New Extensions
+--------------
hunk ./docs/jhc.mkd 231
-* foreign primitive, all primitives are brought into scope with a foreign
-  primitive declaration (barring a few numeric operators) , these can also be
-  used to gain access to C constants, obviating much of the need for a
+ * foreign primitive, all primitives are brought into scope with a foreign
+  primitive declaration, these can also be used to gain access to C constants,
+  obviating much of the need for a
hunk ./docs/jhc.mkd 237
-* SRCLOC_ANNOTATE pragma. This is a generalization of GHCs assert magic. A
+ * SRCLOC_ANNOTATE pragma. This is a generalization of GHCs assert magic. A
hunk ./docs/jhc.mkd 241
-  alternate function is named <code>[function]_srcloc_ann__</code> and must be in
+  alternate function is named [function]_srcloc_ann__ and must be in
hunk ./docs/jhc.mkd 246
-<pre>
hunk ./docs/jhc.mkd 247
-  head :: [a] -> a
-  head (x:xs) = x
-  head [] = error "head - empty list"
+        head :: [a] -> a
+        head (x:xs) = x
+        head [] = error "head - empty list"
hunk ./docs/jhc.mkd 251
-  {-# SRCLOC_ANNOTATE head #-}
+        {-# SRCLOC_ANNOTATE head #-}
hunk ./docs/jhc.mkd 253
-  head_srcloc_ann__ :: String -> [a] -> a
-  head_srcloc_ann__ pos (x:xs) = x
-  head_srcloc_ann__ pos [] = error $ pos ++ ": head - empty list"
+        head_srcloc_ann__ :: String -> [a] -> a
+        head_srcloc_ann__ pos (x:xs) = x
+        head_srcloc_ann__ pos [] = error $ pos ++ ": head - empty list"
hunk ./docs/jhc.mkd 257
-  -- Now, a call to head on an empty list will produce an error message like
-  -- "Main.hs:23: head - empty list"
+        -- Now, a call to head on an empty list will produce an error message like
+        -- "Main.hs:23: head - empty list"
hunk ./docs/jhc.mkd 260
-</pre>
hunk ./docs/jhc.mkd 263
-* SUPERSPECIALIZE pragma. This pragma has the same affect as the SPECIALIZE
-  pragma, but in addition to doing compile-time specialization,
-  SUPERSPECIALIZE performs run-time specialization. A superspecialized
-  function will perform a single check against the type it is called with and
-  depending on the single test, call a specialized version of the function.
-  This can be a huge win when working with overloaded numeric types, imagine a
-  matrix-multiply routine, if the type cannot be determined at compile-time then
-  we would normally be forced to fall back to generic version which may have
-  hundreds of additions and multiplications, each of which must test what type
-  its argument are. If we SUPERSPECIALIZE the multiply routine instead, a single
-  run-time test will be performed and the much much more efficient specialized
-  routine will be used, even if it could not be proven at compile time.
+ * SUPERSPECIALIZE pragma. This pragma has the same affect as the SPECIALIZE
+   pragma, but in addition to doing compile-time specialization,
+   SUPERSPECIALIZE performs run-time specialization. A superspecialized
+   function will perform a single check against the type it is called with and
+   depending on the single test, call a specialized version of the function.
+   This can be a huge win when working with overloaded numeric types, imagine a
+   matrix-multiply routine, if the type cannot be determined at compile-time then
+   we would normally be forced to fall back to generic version which may have
+   hundreds of additions and multiplications, each of which must test what type
+   its argument are. If we SUPERSPECIALIZE the multiply routine instead, a single
+   run-time test will be performed and the much much more efficient specialized
+   routine will be used, even if it could not be proven at compile time.
hunk ./docs/jhc.mkd 276
-* MULTISPECIALIZE pragma. This is equivalent to calling SPECIALIZE against
+ * MULTISPECIALIZE pragma. This is equivalent to calling SPECIALIZE against
hunk ./docs/jhc.mkd 282
-* MULTISUPERSPECIALIZE pragma. This is equivalent to calling SUPERSPECIALIZE
+ * MULTISUPERSPECIALIZE pragma. This is equivalent to calling SUPERSPECIALIZE
hunk ./docs/jhc.mkd 286
-== The story of jhc ==
+The story of jhc
+----------------
hunk ./docs/jhc.mkd 313
-== All is not well in jhc-land ==
+All is not well in jhc-land
+---------------------------
hunk ./docs/jhc.mkd 319
-* It doesn't scale. Basically since jhc compiles the entire standard library
-along with your code, even moderately complex programs can be beyond its
-grasp
+ * It doesn't scale. Basically since jhc compiles the entire standard library
+   along with your code, even moderately complex programs can be beyond its
+   grasp
hunk ./docs/jhc.mkd 324
-not unheard of.
+   not unheard of.
+
+ * There are still some major bugs
hunk ./docs/jhc.mkd 328
-* There are still some major bugs
+ * It leaks memory. The Region inference algorithm is still in the tweaking
+   stage and programs are known to leak memory. for short running programs,
+   this does not seem to be an issue, but anything expected to perform a lot of
+   reductions will probably run out of heap.
hunk ./docs/jhc.mkd 333
-* It leaks memory. The Region inference algorithm is still in the tweaking
-stage and programs are known to leak memory. for short running programs,
-this does not seem to be an issue, but anything expected to perform a lot of
-reductions will probably run out of heap.
+ * it is not done
hunk ./docs/jhc.mkd 335
-* it is not done
+ * Arrays are very slow at the moment.
hunk ./docs/jhc.mkd 337
-* Arrays are very slow at the moment.
+ * only about 70% of nofib compiles at the moment.
hunk ./docs/jhc.mkd 339
-* only about 70% of nofib compiles at the moment.
+ * That said, I am releasing it because people might find the ideas interesting
+   or be able to learn from or borrow of the code.
hunk ./docs/jhc.mkd 342
-* That said, I am releasing it because people might find the ideas interesting
-or be able to learn from or borrow of the code.
+ * Horrible error messages. A few programmer errors (and some non-errors) cause the
+   compiler to quit with an 'error' or pattern match failure.
hunk ./docs/jhc.mkd 345
-* Horrible error messages. A few programmer errors (and some non-errors) cause the
-compiler to quit with an 'error' or pattern match failure.
hunk ./docs/jhc.mkd 346
+References
+----------
hunk ./docs/jhc.mkd 349
-== References ==
+ * Boquist Thesis - http://www.cs.chalmers.se/~boquist/phd/index.html
hunk ./docs/jhc.mkd 351
-* Boquist Thesis - http://www.cs.chalmers.se/~boquist/phd/index.html
+ * Henk paper - http://research.microsoft.com/~simonpj/Papers/henk.ps.gz
hunk ./docs/jhc.mkd 353
-* Henk paper - http://research.microsoft.com/~simonpj/Papers/henk.ps.gz
+ * Pure Type Systems type checking paper
hunk ./docs/jhc.mkd 355
-* Pure Type Systems type checking paper
+ * Secrets of the GHC Inliner -  http://www.research.microsoft.com/~simonpj/Papers/inlining/index.htm
hunk ./docs/jhc.mkd 357
-* Secrets of the GHC Inliner -  http://www.research.microsoft.com/~simonpj/Papers/inlining/index.htm
+ * CPR analysis.
hunk ./docs/jhc.mkd 359
-* CPR analysis.
+ * Strictness analysis w/ HORN clauses
hunk ./docs/jhc.mkd 361
-* Strictness analysis w/ HORN clauses
+ * Typing Haskell in Haskell -  http://www.cse.ogi.edu/~mpj/thih/
hunk ./docs/jhc.mkd 363
-* Typing Haskell in Haskell -  http://www.cse.ogi.edu/~mpj/thih/
+ * Hatchet -  http://www.cs.mu.oz.au/~bjpop/hatchet.html
hunk ./docs/jhc.mkd 365
-* Hatchet -  http://www.cs.mu.oz.au/~bjpop/hatchet.html