[[project @ 2002-08-28 16:02:51 by simonmar] simonmar**20020828160252 Add the beginnings of the "Coding Style Guidelines" for ghc/compiler. ] { addfile ./ghc/docs/comm/the-beast/coding-style.html hunk ./ghc/docs/comm/index.html 55 +
  • Coding style used in + the compiler hunk ./ghc/docs/comm/the-beast/coding-style.html 1 + + + + + The GHC Commentary - Coding Style Guidelines + + + +

    The GHC Commentary - Coding Style Guidelines

    + +

    This is a rough description of some of the coding practices and + style that we use for Haskell code inside ghc/compiler. + +

    The general rule is to stick to the same coding style as is + already used in the file you're editing. If you must make + stylistic changes, commit them separately from functional changes, + so that someone looking back through the change logs can easily + distinguish them. + +

    To literate or not to literate?

    + +

    In GHC we use a mixture of literate (.lhs) and + non-literate (.hs) source. I (Simon M.) prefer to use + non-literate style, because I think the + \begin{code}..\end{code} clutter up the source too much, + and I like to use Haddock-style comments (we haven't tried + processing the whole of GHC with Haddock yet, though). + +

    To CPP or not to CPP?

    + +

    We pass all the compiler sources through CPP. The + -cpp flag is always added by the build system. More + about what you're allowed to do in the way of CPP directives + later. + +

    Compiler versions

    + +

    GHC must be compilable by every major version of GHC from 4.08 + onwards, and itself. It isn't necessary for it to be compilable + by every intermediate development version (that includes last + week's CVS sources), but we mustn't lose compatibility with 4.08 + for the time being, because that's the only version which can be + easily bootstrapped from .hc files. + +

    To maintain compatibility, use HsVersions.h (see + below) where possible, and try to avoid using #ifdef in + the source itself. + +

    The source file

    + +

    We now describe a typical source file, annotating stylistic + choices as we go. + +

    +{-# OPTIONS ... #-}
    +
    + +

    An OPTIONS pragma is optional, but if present it + should go right at the top of the file. Things you might want to + put in OPTIONS include: + +

    + +

    Don't bother putting -cpp or -fglasgow-exts + in the OPTIONS pragma; these are already added to the + command line by the build system. + + +

    +module Foo (
    +   T(..),
    +   foo,	     -- :: T -> T
    + ) where
    +
    + +

    We usually (99% of the time) include an export list. The only + exceptions are perhaps where the export list would list absolutely + everything in the module, and even then sometimes we do it anyway. + +

    It's helpful to give type signatures inside comments in the + export list, but hard to keep them consistent, so we don't always + do that. + +

    +#include "HsVersions.h"
    +
    + +

    HsVersions.h is a CPP header file containing a number + of macros that help smooth out the differences between compiler + versions. It defines, for example, macros for library module + names which have moved between versions. Take a look. + +

    +-- friends
    +import SimplMonad
    +
    +-- GHC
    +import CoreSyn
    +import Id           ( idName, idType )
    +import BasicTypes
    +
    +-- libraries
    +import DATA_IOREF   ( newIORef, readIORef )
    +
    +-- std
    +import List         ( partition )
    +import Maybe        ( fromJust )
    +
    + +

    List imports in the following order: + +

    + +

    Import library modules from the base and + haskell98 packages only. Use #defines in + HsVersions.h when the modules names differ between + versions of GHC (eg. DATA_IOREF in the example above). + For code inside #ifdef GHCI, don't need to worry about GHC + versioning (because we are bootstrapped). + +

    We usually use import specs to give an explicit list of the + entities imported from a module. The main reason for doing this is + so that you can search the file for an entity and find which module + it comes from. However, huge import lists can be a pain to + maintain, so we often omit the import specs when they start to get + long (actually I start omitting them when they don't fit on one + line --Simon M.). Tip: use GHC's -fwarn-unused-imports + flag so that you get notified when an import isn't being used any + more. + +

    If the module can be compiled multiple ways (eg. GHCI + vs. non-GHCI), make sure the imports are properly #ifdefed + too, so as to avoid spurious unused import warnings. + +

    ToDo: finish this + + }