capnp-0.4.0.0: CONTRIBUTING.md
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