Statistics
| Branch: | Tag: | Revision:

root / doc / dev-codestyle.rst @ a41a1eec

History | View | Annotate | Download (16.7 kB)

1 a41a1eec Santi Raffa
Code style guide
2 a41a1eec Santi Raffa
================
3 a41a1eec Santi Raffa
4 a41a1eec Santi Raffa
Python
5 a41a1eec Santi Raffa
------
6 a41a1eec Santi Raffa
7 a41a1eec Santi Raffa
.. highlight:: python
8 a41a1eec Santi Raffa
9 a41a1eec Santi Raffa
These are a few guidelines for Ganeti code and documentation.
10 a41a1eec Santi Raffa
11 a41a1eec Santi Raffa
In simple terms: try to stay consistent with the existing code. `PEP 8`_ says:
12 a41a1eec Santi Raffa
13 a41a1eec Santi Raffa
.. _PEP 8: http://www.python.org/dev/peps/pep-0008/
14 a41a1eec Santi Raffa
15 a41a1eec Santi Raffa
  A style guide is about consistency. Consistency with this style guide is
16 a41a1eec Santi Raffa
  important. Consistency within a project is more important. Consistency
17 a41a1eec Santi Raffa
  within one module or function is most important.
18 a41a1eec Santi Raffa
19 a41a1eec Santi Raffa
.. note::
20 a41a1eec Santi Raffa
21 a41a1eec Santi Raffa
  You might also want to take a look at the `Google style guide`_, since we
22 a41a1eec Santi Raffa
  have some things in common with it.
23 a41a1eec Santi Raffa
24 a41a1eec Santi Raffa
.. _Google style guide: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
25 a41a1eec Santi Raffa
26 a41a1eec Santi Raffa
Indentation
27 a41a1eec Santi Raffa
~~~~~~~~~~~
28 a41a1eec Santi Raffa
In general, always indent using two (2) spaces and don't use tabs.
29 a41a1eec Santi Raffa
30 a41a1eec Santi Raffa
The two spaces should always be relative to the previous level of indentation,
31 a41a1eec Santi Raffa
even if this means that the final number of spaces is not a multiple of 2.
32 a41a1eec Santi Raffa
33 a41a1eec Santi Raffa
When going on a new line inside an open parenthesis, align with the content of
34 a41a1eec Santi Raffa
the parenthesis on the previous line.
35 a41a1eec Santi Raffa
36 a41a1eec Santi Raffa
Valid example::
37 a41a1eec Santi Raffa
38 a41a1eec Santi Raffa
  v = (somevalue,
39 a41a1eec Santi Raffa
       a_function([
40 a41a1eec Santi Raffa
         list_elem, # 7 spaces, but 2 from the previous indentation level
41 a41a1eec Santi Raffa
         another_elem,
42 a41a1eec Santi Raffa
       ]))
43 a41a1eec Santi Raffa
44 a41a1eec Santi Raffa
Formatting strings
45 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~~
46 a41a1eec Santi Raffa
Always use double quotes (``""``), never single quotes (``''``), except for
47 a41a1eec Santi Raffa
existing code. Examples for formatting strings::
48 a41a1eec Santi Raffa
49 a41a1eec Santi Raffa
  var = "value"
50 a41a1eec Santi Raffa
51 a41a1eec Santi Raffa
  # Note: The space character is always on the second line
52 a41a1eec Santi Raffa
  var = ("The quick brown fox jumps over the lazy dog. The quick brown fox"
53 a41a1eec Santi Raffa
         " jumps over the lazy dog. The quick brown fox jumps over the lazy"
54 a41a1eec Santi Raffa
         " dog.")
55 a41a1eec Santi Raffa
56 a41a1eec Santi Raffa
  fn("The quick brown fox jumps over the lazy dog. The quick brown fox jumps"
57 a41a1eec Santi Raffa
     " over the lazy dog.")
58 a41a1eec Santi Raffa
59 a41a1eec Santi Raffa
  fn(constants.CONFIG_VERSION,
60 a41a1eec Santi Raffa
     ("The quick brown fox jumps over the lazy dog. The quick brown fox"
61 a41a1eec Santi Raffa
      " jumps over the lazy dog. The quick brown fox jumps over the lazy"
62 a41a1eec Santi Raffa
      " dog."))
63 a41a1eec Santi Raffa
64 a41a1eec Santi Raffa
Don't format strings like this::
65 a41a1eec Santi Raffa
66 a41a1eec Santi Raffa
  # Don't use single quotes
67 a41a1eec Santi Raffa
  var = 'value'
68 a41a1eec Santi Raffa
69 a41a1eec Santi Raffa
  # Don't use backslash for line continuation
70 a41a1eec Santi Raffa
  var = "The quick brown fox jumps over the lazy dog. The quick brown fox"\
71 a41a1eec Santi Raffa
        " jumps over the lazy dog."
72 a41a1eec Santi Raffa
73 a41a1eec Santi Raffa
  # Space character goes to the beginning of a new line
74 a41a1eec Santi Raffa
  var = ("The quick brown fox jumps over the lazy dog. The quick brown fox "
75 a41a1eec Santi Raffa
         "jumps over the lazy dog. The quick brown fox jumps over the lazy "
76 a41a1eec Santi Raffa
         "dog.")
77 a41a1eec Santi Raffa
78 a41a1eec Santi Raffa
Formatting sequences
79 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~~~~
80 a41a1eec Santi Raffa
Built-in sequence types are list (``[]``), tuple (``()``) and dict (``{}``).
81 a41a1eec Santi Raffa
When splitting to multiple lines, each item should be on its own line and a
82 a41a1eec Santi Raffa
comma must be added on the last line. Don't write multiline dictionaries in
83 a41a1eec Santi Raffa
function calls, except when it's the only parameter. Always indent items by
84 a41a1eec Santi Raffa
two spaces.
85 a41a1eec Santi Raffa
86 a41a1eec Santi Raffa
::
87 a41a1eec Santi Raffa
88 a41a1eec Santi Raffa
  # Short lists
89 a41a1eec Santi Raffa
  var = ["foo", "bar"]
90 a41a1eec Santi Raffa
  var = ("foo", "bar")
91 a41a1eec Santi Raffa
92 a41a1eec Santi Raffa
  # Longer sequences and dictionary
93 a41a1eec Santi Raffa
  var = [
94 a41a1eec Santi Raffa
    constants.XYZ_FILENAME_EXTENSION,
95 a41a1eec Santi Raffa
    constants.FOO_BAR_BAZ,
96 a41a1eec Santi Raffa
    ]
97 a41a1eec Santi Raffa
  var = {
98 a41a1eec Santi Raffa
    "key": func(),
99 a41a1eec Santi Raffa
    "otherkey": None,
100 a41a1eec Santi Raffa
    }
101 a41a1eec Santi Raffa
102 a41a1eec Santi Raffa
  # Multiline tuples as dictionary values
103 a41a1eec Santi Raffa
  var = {
104 a41a1eec Santi Raffa
    "key":
105 a41a1eec Santi Raffa
      ("long value taking the whole line, requiring you to go to a new one",
106 a41a1eec Santi Raffa
       other_value),
107 a41a1eec Santi Raffa
  }
108 a41a1eec Santi Raffa
109 a41a1eec Santi Raffa
  # Function calls
110 a41a1eec Santi Raffa
  var = frozenset([1, 2, 3])
111 a41a1eec Santi Raffa
  var = F({
112 a41a1eec Santi Raffa
    "xyz": constants.XYZ,
113 a41a1eec Santi Raffa
    "abc": constants.ABC,
114 a41a1eec Santi Raffa
    })
115 a41a1eec Santi Raffa
116 a41a1eec Santi Raffa
  # Wrong
117 a41a1eec Santi Raffa
  F(123, "Hello World",
118 a41a1eec Santi Raffa
    { "xyz": constants.XYZ })
119 a41a1eec Santi Raffa
120 a41a1eec Santi Raffa
We consider tuples as data structures, not containers. So in general please
121 a41a1eec Santi Raffa
use lists when dealing with a sequence of homogeneous items, and tuples when
122 a41a1eec Santi Raffa
dealing with heterogeneous items.
123 a41a1eec Santi Raffa
124 a41a1eec Santi Raffa
Passing arguments
125 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~
126 a41a1eec Santi Raffa
Positional arguments must be passed as positional arguments, keyword arguments
127 a41a1eec Santi Raffa
must be passed as keyword arguments. Everything else will be difficult to
128 a41a1eec Santi Raffa
maintain.
129 a41a1eec Santi Raffa
130 a41a1eec Santi Raffa
::
131 a41a1eec Santi Raffa
132 a41a1eec Santi Raffa
  # Function signature
133 a41a1eec Santi Raffa
  def F(data, key, salt=None, key_selector=None):
134 a41a1eec Santi Raffa
    pass
135 a41a1eec Santi Raffa
136 a41a1eec Santi Raffa
  # Yes
137 a41a1eec Santi Raffa
  F("The quick brown fox", "123456")
138 a41a1eec Santi Raffa
  F("The quick brown fox", "123456", salt="abc")
139 a41a1eec Santi Raffa
  F("The quick brown fox", "123456", key_selector="xyz")
140 a41a1eec Santi Raffa
  F("The quick brown fox", "123456", salt="foo", key_selector="xyz")
141 a41a1eec Santi Raffa
142 a41a1eec Santi Raffa
  # No: Passing keyword arguments as positional argument
143 a41a1eec Santi Raffa
  F("The quick brown fox", "123456", "xyz", "bar")
144 a41a1eec Santi Raffa
145 a41a1eec Santi Raffa
  # No: Passing positional arguments as keyword argument
146 a41a1eec Santi Raffa
  F(salt="xyz", data="The quick brown fox", key="123456", key_selector="xyz")
147 a41a1eec Santi Raffa
148 a41a1eec Santi Raffa
Docstrings
149 a41a1eec Santi Raffa
~~~~~~~~~~
150 a41a1eec Santi Raffa
151 a41a1eec Santi Raffa
.. note::
152 a41a1eec Santi Raffa
153 a41a1eec Santi Raffa
  `PEP 257`_ is the canonical document, unless epydoc overrules it (e.g. in how
154 a41a1eec Santi Raffa
  to document the type of an argument).
155 a41a1eec Santi Raffa
156 a41a1eec Santi Raffa
For docstrings, the recommended format is epytext_, to be processed via
157 a41a1eec Santi Raffa
epydoc_. There is an ``apidoc`` target that builds the documentation and puts it
158 a41a1eec Santi Raffa
into the doc/api subdir. Note that we currently use epydoc version 3.0.
159 a41a1eec Santi Raffa
160 a41a1eec Santi Raffa
.. _PEP 257: http://www.python.org/dev/peps/pep-0257/
161 a41a1eec Santi Raffa
.. _epytext: http://epydoc.sourceforge.net/manual-epytext.html
162 a41a1eec Santi Raffa
.. _epydoc: http://epydoc.sourceforge.net/
163 a41a1eec Santi Raffa
164 a41a1eec Santi Raffa
Note that one-line docstrings are only accepted in the unittests.
165 a41a1eec Santi Raffa
166 a41a1eec Santi Raffa
Rules for writing the docstrings (mostly standard Python rules):
167 a41a1eec Santi Raffa
168 a41a1eec Santi Raffa
* the docstring should start with a sentence, with punctuation at the end,
169 a41a1eec Santi Raffa
  summarizing the the aim of what is being described. This sentence cannot be
170 a41a1eec Santi Raffa
  longer than one line
171 a41a1eec Santi Raffa
* the second line should be blank
172 a41a1eec Santi Raffa
* afterwards the rest of the docstring
173 a41a1eec Santi Raffa
* special epytext tags should come at the end
174 a41a1eec Santi Raffa
* multi-line docstrings must finish with an empty line
175 a41a1eec Santi Raffa
* do not try to make a table using lots of whitespace
176 a41a1eec Santi Raffa
* use ``L{}`` and ``C{}`` where appropriate
177 a41a1eec Santi Raffa
178 a41a1eec Santi Raffa
Here's an example::
179 a41a1eec Santi Raffa
180 a41a1eec Santi Raffa
  def fn(foo, bar):
181 a41a1eec Santi Raffa
    """Compute the sum of foo and bar.
182 a41a1eec Santi Raffa
183 a41a1eec Santi Raffa
    This functions builds the sum of foo and bar. It's a simple function.
184 a41a1eec Santi Raffa
185 a41a1eec Santi Raffa
    @type foo: int
186 a41a1eec Santi Raffa
    @param foo: First parameter.
187 a41a1eec Santi Raffa
    @type bar: float
188 a41a1eec Santi Raffa
    @param bar: The second parameter. This line is longer
189 a41a1eec Santi Raffa
      to show wrapping.
190 a41a1eec Santi Raffa
    @rtype: float
191 a41a1eec Santi Raffa
    @return: the sum of the two numbers
192 a41a1eec Santi Raffa
193 a41a1eec Santi Raffa
    """
194 a41a1eec Santi Raffa
    return foo + bar
195 a41a1eec Santi Raffa
196 a41a1eec Santi Raffa
Some rules of thumb which should be applied with good judgement on a case-to-
197 a41a1eec Santi Raffa
case basis:
198 a41a1eec Santi Raffa
199 a41a1eec Santi Raffa
* If the meaning of parameters is already obvious given its name and the
200 a41a1eec Santi Raffa
  methods description, don't document it again. Just add a ``@type`` tag.
201 a41a1eec Santi Raffa
* Refer to the base methods documentation when overwriting methods. Only
202 a41a1eec Santi Raffa
  document more if it applies to the current subclass only, or if you want to
203 a41a1eec Santi Raffa
  clarify on the meaning of parameters for the special subclass.
204 a41a1eec Santi Raffa
205 a41a1eec Santi Raffa
Rules for classes and modules
206 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207 a41a1eec Santi Raffa
As `PEP 257`_ says, the docstrings of classes should document their attributes
208 a41a1eec Santi Raffa
and the docstrings of modules should shortly document the exported
209 a41a1eec Santi Raffa
functions/variables/etc.
210 a41a1eec Santi Raffa
211 a41a1eec Santi Raffa
See for example the pydoc output for the ``os`` or ``ConfigParser`` standard
212 a41a1eec Santi Raffa
modules.
213 a41a1eec Santi Raffa
214 a41a1eec Santi Raffa
Haskell
215 a41a1eec Santi Raffa
-------
216 a41a1eec Santi Raffa
217 a41a1eec Santi Raffa
.. highlight:: haskell
218 a41a1eec Santi Raffa
219 a41a1eec Santi Raffa
The most important consideration is, as usual, to stay consistent with the
220 a41a1eec Santi Raffa
existing code.
221 a41a1eec Santi Raffa
222 a41a1eec Santi Raffa
As there's no "canonical" style guide for Haskell, this code style has been
223 a41a1eec Santi Raffa
inspired from a few online resources, including the style guide for the
224 a41a1eec Santi Raffa
`Snap framework`_, `this style guide`_ and `this other style guide`_.
225 a41a1eec Santi Raffa
226 a41a1eec Santi Raffa
.. _Snap framework: http://snapframework.com/docs/style-guide
227 a41a1eec Santi Raffa
.. _this style guide: https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
228 a41a1eec Santi Raffa
.. _this other style guide: http://www.cs.caltech.edu/courses/cs11/material/haskell/misc/haskell_style_guide.html
229 a41a1eec Santi Raffa
230 a41a1eec Santi Raffa
Files
231 a41a1eec Santi Raffa
~~~~~
232 a41a1eec Santi Raffa
Use ordinary, non-`literate`_ Haskell ``.hs`` files.
233 a41a1eec Santi Raffa
234 a41a1eec Santi Raffa
.. _literate: http://www.haskell.org/haskellwiki/Literate_programming
235 a41a1eec Santi Raffa
236 a41a1eec Santi Raffa
Use proper copyright headers, and proper Haddock style documentation headers::
237 a41a1eec Santi Raffa
238 a41a1eec Santi Raffa
  {-| Short module summary.
239 a41a1eec Santi Raffa
240 a41a1eec Santi Raffa
  Longer module description.
241 a41a1eec Santi Raffa
242 a41a1eec Santi Raffa
  -}
243 a41a1eec Santi Raffa
244 a41a1eec Santi Raffa
  {-
245 a41a1eec Santi Raffa
246 a41a1eec Santi Raffa
  Copyright (C) ...
247 a41a1eec Santi Raffa
248 a41a1eec Santi Raffa
  This program is free software ...
249 a41a1eec Santi Raffa
250 a41a1eec Santi Raffa
  -}
251 a41a1eec Santi Raffa
252 a41a1eec Santi Raffa
If there are module-level pragmas add them right at the top, before the short
253 a41a1eec Santi Raffa
summary.
254 a41a1eec Santi Raffa
255 a41a1eec Santi Raffa
Imports
256 a41a1eec Santi Raffa
~~~~~~~
257 a41a1eec Santi Raffa
Imports should be grouped into the following groups and inside each group they
258 a41a1eec Santi Raffa
should be sorted alphabetically:
259 a41a1eec Santi Raffa
260 a41a1eec Santi Raffa
1. standard library imports
261 a41a1eec Santi Raffa
2. third-party imports
262 a41a1eec Santi Raffa
3. local imports
263 a41a1eec Santi Raffa
264 a41a1eec Santi Raffa
It is allowed to use qualified imports with short names for:
265 a41a1eec Santi Raffa
266 a41a1eec Santi Raffa
* standard library (e.g. ``import qualified Data.Map as M``)
267 a41a1eec Santi Raffa
* local imports (e.g. ``import qualified Ganeti.Constants as C``), although
268 a41a1eec Santi Raffa
  this form should be kept to a minimum
269 a41a1eec Santi Raffa
270 a41a1eec Santi Raffa
Indentation
271 a41a1eec Santi Raffa
~~~~~~~~~~~
272 a41a1eec Santi Raffa
Use only spaces, never tabs. Indentation level is 2 characters. For Emacs,
273 a41a1eec Santi Raffa
this means setting the variable ``haskell-indent-offset`` to 2.
274 a41a1eec Santi Raffa
275 a41a1eec Santi Raffa
Line length should be at most 78 chars, and 72 chars inside comments.
276 a41a1eec Santi Raffa
277 a41a1eec Santi Raffa
Use indentation-based structure, and not braces/semicolons.
278 a41a1eec Santi Raffa
279 a41a1eec Santi Raffa
.. note::
280 a41a1eec Santi Raffa
281 a41a1eec Santi Raffa
  Special indendation of if/then/else construct
282 a41a1eec Santi Raffa
283 a41a1eec Santi Raffa
  For the ``do`` notation, the ``if-then-else`` construct has a non-intuitive
284 a41a1eec Santi Raffa
  behaviour. As such, the indentation of ``if-then-else`` (both in ``do``
285 a41a1eec Santi Raffa
  blocks and in normal blocks) should be as follows::
286 a41a1eec Santi Raffa
287 a41a1eec Santi Raffa
    if condition
288 a41a1eec Santi Raffa
      then expr1
289 a41a1eec Santi Raffa
      else expr2
290 a41a1eec Santi Raffa
291 a41a1eec Santi Raffa
  i.e. indent the then/else lines with another level. This can be accomplished
292 a41a1eec Santi Raffa
  in Emacs by setting the variable ``haskell-indent-thenelse`` to 2 (from the
293 a41a1eec Santi Raffa
  default of zero).
294 a41a1eec Santi Raffa
295 a41a1eec Santi Raffa
If you have more than one line of code please newline/indent after the "=". Do
296 a41a1eec Santi Raffa
`not` do::
297 a41a1eec Santi Raffa
298 a41a1eec Santi Raffa
  f x = let y = x + 1
299 a41a1eec Santi Raffa
        in  y
300 a41a1eec Santi Raffa
301 a41a1eec Santi Raffa
Instead do::
302 a41a1eec Santi Raffa
303 a41a1eec Santi Raffa
  f x =
304 a41a1eec Santi Raffa
    let y = x + 1
305 a41a1eec Santi Raffa
    in  y
306 a41a1eec Santi Raffa
307 a41a1eec Santi Raffa
or if it is just one line::
308 a41a1eec Santi Raffa
309 a41a1eec Santi Raffa
  f x = x + 1
310 a41a1eec Santi Raffa
311 a41a1eec Santi Raffa
Multiline strings
312 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~
313 a41a1eec Santi Raffa
Multiline strings are created by closing a line with a backslash and starting
314 a41a1eec Santi Raffa
the following line with a backslash, keeping the indentation level constant.
315 a41a1eec Santi Raffa
Whitespaces go on the new line, right after the backslash.
316 a41a1eec Santi Raffa
317 a41a1eec Santi Raffa
::
318 a41a1eec Santi Raffa
319 a41a1eec Santi Raffa
  longString :: String
320 a41a1eec Santi Raffa
  longString = "This is a very very very long string that\
321 a41a1eec Santi Raffa
               \ needs to be split in two lines"
322 a41a1eec Santi Raffa
323 a41a1eec Santi Raffa
Data declarations
324 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~
325 a41a1eec Santi Raffa
.. warning::
326 a41a1eec Santi Raffa
  Note that this is different from the Python style!
327 a41a1eec Santi Raffa
328 a41a1eec Santi Raffa
When declaring either data types, or using list literals, etc., the columns
329 a41a1eec Santi Raffa
should be aligned, and for lists use a comma at the start of the line, not at
330 a41a1eec Santi Raffa
the end. Examples::
331 a41a1eec Santi Raffa
332 a41a1eec Santi Raffa
  data OpCode = OpStartupInstance ...
333 a41a1eec Santi Raffa
              | OpShutdownInstance ...
334 a41a1eec Santi Raffa
              | ...
335 a41a1eec Santi Raffa
336 a41a1eec Santi Raffa
  data Node = Node { name :: String
337 a41a1eec Santi Raffa
                   , ip   :: String
338 a41a1eec Santi Raffa
                   , ...
339 a41a1eec Santi Raffa
                   }
340 a41a1eec Santi Raffa
341 a41a1eec Santi Raffa
  myList = [ value1
342 a41a1eec Santi Raffa
           , value2
343 a41a1eec Santi Raffa
           , value3
344 a41a1eec Santi Raffa
           ]
345 a41a1eec Santi Raffa
346 a41a1eec Santi Raffa
The choice of whether to wrap the first element or not is up to you; the
347 a41a1eec Santi Raffa
following is also allowed::
348 a41a1eec Santi Raffa
349 a41a1eec Santi Raffa
  myList =
350 a41a1eec Santi Raffa
    [ value1
351 a41a1eec Santi Raffa
    , value2
352 a41a1eec Santi Raffa
    ]
353 a41a1eec Santi Raffa
354 a41a1eec Santi Raffa
White space
355 a41a1eec Santi Raffa
~~~~~~~~~~~
356 a41a1eec Santi Raffa
Like in Python, surround binary operators with one space on either side. Do no
357 a41a1eec Santi Raffa
insert a space after a lamda::
358 a41a1eec Santi Raffa
359 a41a1eec Santi Raffa
  -- bad
360 a41a1eec Santi Raffa
  map (\ n -> ...) lst
361 a41a1eec Santi Raffa
  -- good
362 a41a1eec Santi Raffa
  foldl (\x y -> ...) ...
363 a41a1eec Santi Raffa
364 a41a1eec Santi Raffa
Use a blank line between top-level definitions, but no blank lines between
365 a41a1eec Santi Raffa
either the comment and the type signature or between the type signature and
366 a41a1eec Santi Raffa
the actual function definition.
367 a41a1eec Santi Raffa
368 a41a1eec Santi Raffa
.. note::
369 a41a1eec Santi Raffa
  Ideally it would be two blank lines between top-level definitions, but the
370 a41a1eec Santi Raffa
  code only has one now.
371 a41a1eec Santi Raffa
372 a41a1eec Santi Raffa
As always, no trailing spaces. Ever.
373 a41a1eec Santi Raffa
374 a41a1eec Santi Raffa
Spaces after comma
375 a41a1eec Santi Raffa
******************
376 a41a1eec Santi Raffa
377 a41a1eec Santi Raffa
Instead of::
378 a41a1eec Santi Raffa
379 a41a1eec Santi Raffa
  ("a","b")
380 a41a1eec Santi Raffa
381 a41a1eec Santi Raffa
write::
382 a41a1eec Santi Raffa
383 a41a1eec Santi Raffa
  ("a", "b")
384 a41a1eec Santi Raffa
385 a41a1eec Santi Raffa
Naming
386 a41a1eec Santi Raffa
~~~~~~
387 a41a1eec Santi Raffa
Functions should be named in mixedCase style, and types in CamelCase. Function
388 a41a1eec Santi Raffa
arguments and local variables should be mixedCase.
389 a41a1eec Santi Raffa
390 a41a1eec Santi Raffa
When using acronyms, ones longer than 2 characters should be typed capitalised,
391 a41a1eec Santi Raffa
not fully upper-cased (e.g. ``Http``, not ``HTTP``).
392 a41a1eec Santi Raffa
393 a41a1eec Santi Raffa
For variable names, use descriptive names; it is only allowed to use very
394 a41a1eec Santi Raffa
short names (e.g. ``a``, ``b``, ``i``, ``j``, etc.) when:
395 a41a1eec Santi Raffa
396 a41a1eec Santi Raffa
* the function is trivial, e.g.::
397 a41a1eec Santi Raffa
398 a41a1eec Santi Raffa
    sum x y = x + y
399 a41a1eec Santi Raffa
400 a41a1eec Santi Raffa
* we talk about some very specific cases, e.g.
401 a41a1eec Santi Raffa
  iterators or accumulators in folds::
402 a41a1eec Santi Raffa
403 a41a1eec Santi Raffa
    map (\v -> v + 1) lst
404 a41a1eec Santi Raffa
405 a41a1eec Santi Raffa
* using ``x:xs`` for list elements and lists, etc.
406 a41a1eec Santi Raffa
407 a41a1eec Santi Raffa
In general, short/one-letter names are allowed when we deal with polymorphic
408 a41a1eec Santi Raffa
values; for example the standard map definition from Prelude::
409 a41a1eec Santi Raffa
410 a41a1eec Santi Raffa
  map :: (a -> b) -> [a] -> [b]
411 a41a1eec Santi Raffa
  map _ []     = []
412 a41a1eec Santi Raffa
  map f (x:xs) = f x : map f xs
413 a41a1eec Santi Raffa
414 a41a1eec Santi Raffa
In this example, neither the ``a`` nor ``b`` types are known to the map
415 a41a1eec Santi Raffa
function, so we cannot give them more explicit names. Since the body of the
416 a41a1eec Santi Raffa
function is trivial, the variables used are longer.
417 a41a1eec Santi Raffa
418 a41a1eec Santi Raffa
However, if we deal with explicit types or values, their names should be
419 a41a1eec Santi Raffa
descriptive.
420 a41a1eec Santi Raffa
421 a41a1eec Santi Raffa
.. todo: add a nice example here.
422 a41a1eec Santi Raffa
423 a41a1eec Santi Raffa
Finally, the naming should look familiar to people who just read the
424 a41a1eec Santi Raffa
Prelude/standard libraries.
425 a41a1eec Santi Raffa
426 a41a1eec Santi Raffa
Naming for updated values
427 a41a1eec Santi Raffa
*************************
428 a41a1eec Santi Raffa
429 a41a1eec Santi Raffa
.. highlight:: python
430 a41a1eec Santi Raffa
431 a41a1eec Santi Raffa
Since one cannot update a value in Haskell, this presents a particular problem
432 a41a1eec Santi Raffa
on the naming of new versions of the same value. For example, the following
433 a41a1eec Santi Raffa
code in Python::
434 a41a1eec Santi Raffa
435 a41a1eec Santi Raffa
  def failover(pri, sec, inst):
436 a41a1eec Santi Raffa
    pri.removePrimary(inst)
437 a41a1eec Santi Raffa
    pri.addSecondary(inst)
438 a41a1eec Santi Raffa
    sec.removeSecondary(inst)
439 a41a1eec Santi Raffa
    sec.addPrimary(inst)
440 a41a1eec Santi Raffa
441 a41a1eec Santi Raffa
.. highlight:: haskell
442 a41a1eec Santi Raffa
443 a41a1eec Santi Raffa
becomes in Haskell something like the following::
444 a41a1eec Santi Raffa
445 a41a1eec Santi Raffa
  failover pri sec inst =
446 a41a1eec Santi Raffa
    let pri'  = removePrimary pri inst
447 a41a1eec Santi Raffa
        pri'' = addSecondary pri' inst
448 a41a1eec Santi Raffa
        sec'  = removeSecondary sec inst
449 a41a1eec Santi Raffa
        sec'' = addPrimary sec' inst
450 a41a1eec Santi Raffa
    in (pri'', sec'')
451 a41a1eec Santi Raffa
452 a41a1eec Santi Raffa
When updating values, one should add single quotes to the name for up to three
453 a41a1eec Santi Raffa
new names (e.g. ``inst``, ``inst'``, ``inst''``, ``inst'''``) and otherwise
454 a41a1eec Santi Raffa
use numeric suffixes (``inst1``, ``inst2``, ``inst3``, ..., ``inst8``), but
455 a41a1eec Santi Raffa
that many updates is already bad style and thus should be avoided.
456 a41a1eec Santi Raffa
457 a41a1eec Santi Raffa
Type signatures
458 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~
459 a41a1eec Santi Raffa
460 a41a1eec Santi Raffa
Always declare types for functions (and any other top-level bindings).
461 a41a1eec Santi Raffa
462 a41a1eec Santi Raffa
If in doubt, feel free to declare the type of the variables/bindings in a
463 a41a1eec Santi Raffa
complex expression; this usually means the expression is too complex, however.
464 a41a1eec Santi Raffa
465 a41a1eec Santi Raffa
Similarly, provide Haddock-style comments for top-level definitions.
466 a41a1eec Santi Raffa
467 a41a1eec Santi Raffa
Parentheses, point free style
468 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
469 a41a1eec Santi Raffa
470 a41a1eec Santi Raffa
Prefer the so-called point-free style to extra parentheses::
471 a41a1eec Santi Raffa
472 a41a1eec Santi Raffa
  -- bad
473 a41a1eec Santi Raffa
  let a = f ( g ( h x) )
474 a41a1eec Santi Raffa
  -- better
475 a41a1eec Santi Raffa
  let b = f $ g $ h x
476 a41a1eec Santi Raffa
  -- best
477 a41a1eec Santi Raffa
  let c = f . g . h $ x
478 a41a1eec Santi Raffa
479 a41a1eec Santi Raffa
Language features
480 a41a1eec Santi Raffa
~~~~~~~~~~~~~~~~~
481 a41a1eec Santi Raffa
482 a41a1eec Santi Raffa
Extensions
483 a41a1eec Santi Raffa
**********
484 a41a1eec Santi Raffa
485 a41a1eec Santi Raffa
It is recommended to keep the use of extensions to a minimum, so that the code
486 a41a1eec Santi Raffa
can be understood even if one is familiar with just Haskel98/Haskell2010. That
487 a41a1eec Santi Raffa
said, some extensions are very common and useful, so they are recommended:
488 a41a1eec Santi Raffa
489 a41a1eec Santi Raffa
* `Bang patterns`_: useful when you want to enforce strict evaluation (and better
490 a41a1eec Santi Raffa
  than repeated use of ``seq``)
491 a41a1eec Santi Raffa
* CPP: a few modules need this in order to account for configure-time options;
492 a41a1eec Santi Raffa
  don't overuse it, since it breaks multi-line strings
493 a41a1eec Santi Raffa
* `Template Haskell`_: we use this for automatically deriving JSON instances and
494 a41a1eec Santi Raffa
  other similar boiler-plate
495 a41a1eec Santi Raffa
496 a41a1eec Santi Raffa
.. _Bang patterns: http://www.haskell.org/ghc/docs/latest/html/users_guide/bang-patterns.html
497 a41a1eec Santi Raffa
.. _Template Haskell: http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html
498 a41a1eec Santi Raffa
499 a41a1eec Santi Raffa
Such extensions should be declared using the ``Language`` pragma::
500 a41a1eec Santi Raffa
501 a41a1eec Santi Raffa
  {-# Language BangPatterns #-}
502 a41a1eec Santi Raffa
503 a41a1eec Santi Raffa
  {-| This is a small module... -}
504 a41a1eec Santi Raffa
505 a41a1eec Santi Raffa
Comments
506 a41a1eec Santi Raffa
********
507 a41a1eec Santi Raffa
508 a41a1eec Santi Raffa
Always use proper sentences; start with a capital letter and use punctuation
509 a41a1eec Santi Raffa
in top level comments::
510 a41a1eec Santi Raffa
511 a41a1eec Santi Raffa
  -- | A function that does something.
512 a41a1eec Santi Raffa
  f :: ...
513 a41a1eec Santi Raffa
514 a41a1eec Santi Raffa
For inline comments, start with a capital letter but no ending punctuation.
515 a41a1eec Santi Raffa
Furthermore, align the comments together with a 2-space width from the end of
516 a41a1eec Santi Raffa
the item being commented::
517 a41a1eec Santi Raffa
518 a41a1eec Santi Raffa
  data Maybe a = Nothing  -- ^ Represents empty container
519 a41a1eec Santi Raffa
               | Just a   -- ^ Represents a single value
520 a41a1eec Santi Raffa
521 a41a1eec Santi Raffa
The comments should be clear enough so that one doesn't need to look at the
522 a41a1eec Santi Raffa
code to understand what the item does/is.
523 a41a1eec Santi Raffa
524 a41a1eec Santi Raffa
Use ``-- |`` to write doc strings rather than bare comment with ``--``.
525 a41a1eec Santi Raffa
526 a41a1eec Santi Raffa
Tools
527 a41a1eec Santi Raffa
*****
528 a41a1eec Santi Raffa
529 a41a1eec Santi Raffa
We generate the API documentation via Haddock, and as such the comments should
530 a41a1eec Santi Raffa
be correct (syntax-wise) for it. Use markup, but sparingly.
531 a41a1eec Santi Raffa
532 a41a1eec Santi Raffa
We use hlint_ as a lint checker; the code is currently lint-clean, so you must
533 a41a1eec Santi Raffa
not add any warnings/errors.
534 a41a1eec Santi Raffa
535 a41a1eec Santi Raffa
.. _hlint: http://community.haskell.org/~ndm/darcs/hlint/hlint.htm
536 a41a1eec Santi Raffa
537 a41a1eec Santi Raffa
Use these two commands during development::
538 a41a1eec Santi Raffa
539 a41a1eec Santi Raffa
  make hs-apidoc
540 a41a1eec Santi Raffa
  make hlint
541 a41a1eec Santi Raffa
542 a41a1eec Santi Raffa
QuickCheck best practices
543 a41a1eec Santi Raffa
*************************
544 a41a1eec Santi Raffa
545 a41a1eec Santi Raffa
If you have big type that takes time to generate and several properties to
546 a41a1eec Santi Raffa
test on that, by default 500 of those big instances are generated for each
547 a41a1eec Santi Raffa
property. In many cases, it would be sufficient to only generate those 500
548 a41a1eec Santi Raffa
instances once and test all properties on those. To do this, create a property
549 a41a1eec Santi Raffa
that uses ``conjoin`` to combine several properties into one. Use
550 a41a1eec Santi Raffa
``printTestCase`` to add expressive error messages. For example::
551 a41a1eec Santi Raffa
552 a41a1eec Santi Raffa
  prop_myMegaProp :: myBigType -> Property
553 a41a1eec Santi Raffa
  prop_myMegaProp b =
554 a41a1eec Santi Raffa
    conjoin
555 a41a1eec Santi Raffa
      [ printTestCase
556 a41a1eec Santi Raffa
          ("Something failed horribly here: " ++ show b) (subProperty1 b)
557 a41a1eec Santi Raffa
      , printTestCase
558 a41a1eec Santi Raffa
          ("Something else failed horribly here: " ++ show b)
559 a41a1eec Santi Raffa
          (subProperty2 b)
560 a41a1eec Santi Raffa
      , -- more properties here ...
561 a41a1eec Santi Raffa
      ]
562 a41a1eec Santi Raffa
563 a41a1eec Santi Raffa
  subProperty1 :: myBigType -> Bool
564 a41a1eec Santi Raffa
  subProperty1 b = ...
565 a41a1eec Santi Raffa
566 a41a1eec Santi Raffa
  subProperty2 :: myBigType -> Property
567 a41a1eec Santi Raffa
  subProperty2 b = ...
568 a41a1eec Santi Raffa
569 a41a1eec Santi Raffa
  ...
570 a41a1eec Santi Raffa
571 a41a1eec Santi Raffa
Maybe Generation
572 a41a1eec Santi Raffa
''''''''''''''''
573 a41a1eec Santi Raffa
574 a41a1eec Santi Raffa
Use ``genMaybe genSomething`` to create ``Maybe`` instances of something
575 a41a1eec Santi Raffa
including some ``Nothing`` instances.
576 a41a1eec Santi Raffa
577 a41a1eec Santi Raffa
Use ``Just <$> genSomething`` to generate only ``Just`` instances of
578 a41a1eec Santi Raffa
something.
579 a41a1eec Santi Raffa
580 a41a1eec Santi Raffa
String Generation
581 a41a1eec Santi Raffa
'''''''''''''''''
582 a41a1eec Santi Raffa
583 a41a1eec Santi Raffa
To generate strings, consider using ``genName`` instead of ``arbitrary``.
584 a41a1eec Santi Raffa
``arbitrary`` has the tendency to generate strings that are too long.