Firstly, thanks! The easiest way to contribute is just feedback: use the library, let me know how the experience was. Tell me how you're using the library. Open issues if you find them. If you're looking to hack on the library, great! If you don't have something specific in mind and you're looking for a task to get your feet wet, there are a number of open issues labeled ["good first issue"](https://github.com/zenhack/haskell-capnp/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22); these are self-contained, well-defined tasks that touch a relatively small portion of the code, and so don't require deep understanding of the structure of the library as a whole; as such they're great for new contributors. If you want to work on an existing issue, leave a comment on the issue saying you're planning on tacking a whack at it. I'll probably reply before too long. Send a pull request when you've got something to review. # Comments A couple guidelines re comments: * For implementation notes inside the code, we adopt GHC's [Note convention][2]. * Each thing that is exported from a module must have a haddock comment briefly describing what it does and how to use it. Most non-exported top level identifiers should have these as well, but this is more flexible. * Prefer end-of-line (`--`) comments over block comments; very large block comments can confuse syntax highlighting in some editors. # Style Guide Generally, do what the rest of the code does. Much of this section is bikeshed, but consistency is worth a bit of that. ## Formatting/Layout * [stylish-haskell][1] takes care of most formatting issues. If it wants to change your code, let it; this solves a lot of consistency issues without us needing to remember anything, and it gets run as part of our CI, so failing to use it will likely cause failures. Running `./format.sh` will apply it to the entire source tree, using this project's rules, but we recommend you configure your editor to use it automatically. * Use a tabstop of 4 spaces in Haskell source code, 2 spaces in the cabal file. Where stylish-haskell doesn't contradict you, use more regular indentation. Bad: ```haskell data MyVariant = Apples Int | Oranges Bool ``` Good: ```haskell data MyVariant = Apples Int | Oranges Bool ``` Bad: ```haskell myAction val = do print val c <- getChar putChar (toUpper c) ``` Good: ```haskell myAction Val = do print val c <- getChar putChar (toUpper c) ``` This goes for cabal files as well. Bad: ```haskell build-depends: base >= 4.8 && < 5.0 , text >= 1.2 && < 2.0 , bytestring >= 0.10 && < 0.11 , array >= 0.5 && < 0.6 ... ``` Good: ```haskell build-depends: base >= 4.8 && < 5.0 , text >= 1.2 && < 2.0 , bytestring >= 0.10 && < 0.11 , array >= 0.5 && < 0.6 ... ``` The same rule applies for other constructs. ## Imports Some guidelines re: imports: * Favor qualified imports or importing specific items. Unqualified imports are acceptable in a few cases, where you're using a ton of stuff from a single module, but try to avoid them, especially with libraries whose API is not very very stable. * Wildcard imports of all of a type's data constructors/type class's methods (`MonadThrow(..)`) are more acceptable, though still prefer specifying specific ones if you're only using a couple. * Separate imports of modules within our own codebase from ones from outside of it. * Within each of those groups, group imports into four distinct sections, separated by a single blank line (some of these may be absent): ```haskell -- "negative" imports: import Prelude hiding (length) -- unqualified imports; try to avoid these, but sometimes if you've got -- a module that's doing nothing but bitwhacking, it can make sense: import Data.Bits import Data.Word -- imports of specific values import Control.Monad(when, void) import Control.Monad.Catch(throwM) -- qualified module imports: import qualified Data.ByteString as BS -- same structure for modules within our library: import Capnp.Untyped hiding (length) import Capnp.Bits import Capnp.TraversalLimit(defaultLimit, evalLimitT) import qualified Capnp.Message as M import qualified Capnp.Basics as B ``` The formatter will take care of formatting the sections correctly, as long as you keep the line-breaks right. [1]: https://github.com/jaspervdj/stylish-haskell [2]: https://ghc.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Commentsinthesourcecode