|
| 1 | +# Style Guide |
| 2 | + |
| 3 | +The goal of this guide is to provide a standard for MODFLOW 6 contributors to follow, in pursuit of consistent, readable, well-organized, and unsurprising source code. |
| 4 | + |
| 5 | +MODFLOW 6 is written in Fortran — largely Fortran 2003, with sparse use of a few 2008 language features. This guide assumes familiarity with the Fortran language. |
| 6 | + |
| 7 | +## Amendments |
| 8 | + |
| 9 | +Suggestions to change or extend the style conventions are welcome. Suggestions should be accompanied by a good case for the change. Bear in mind that a goal of this guide is to minimize time spent thinking about questions of style. |
| 10 | + |
| 11 | +## Conventions |
| 12 | + |
| 13 | +* Use `CamelCase` for source file names. |
| 14 | +* Use `CamelCase` for module and derived type names. |
| 15 | +* Use a noun or noun phrase for module and derived type names. |
| 16 | +* Use `snake_case` for procedure names. |
| 17 | +* Use a verb or verb phrase for procedure names. |
| 18 | +* End module names with `...Module`. |
| 19 | +* Derived type names may, but need not, end with `...Type`. |
| 20 | +* If a source file exists primarily to host a module, name the source file and module identically, except for trailing `...Module`. |
| 21 | +* If a module exists primarily to host a type, name the module and type identically, except for trailing `...Module` and `...Type`. |
| 22 | +* Include the module/subroutine/function name in `end module`, `end subroutine` and `end function` statements. |
| 23 | +* Don't end procedures with a `return` statement; use `return` only to return early. |
| 24 | +* Avoid `goto` statements. |
| 25 | +* Use `implicit none` in all modules. |
| 26 | +* Avoid `implicit none` in procedures except where necessary (e.g. interface bodies). |
| 27 | +* Don't use implicit dummy arguments or local variables. |
| 28 | +* Make modules `private` by default. Mark `public` types and procedures explicitly. |
| 29 | +* Specify precision for logicals, integers and reals with the data types defined in `src/Utilities/kind.f90`. |
| 30 | +* Avoid empty comments. |
| 31 | +* Avoid comments starting with `--`. |
| 32 | +* Include blank lines between: |
| 33 | + * module declaration and `use...` statements |
| 34 | + * `use...` statements and procedure declarations |
| 35 | + * derived type declaration and member variables |
| 36 | + * member variables and `contains` statements |
| 37 | +* Prefer explicitly specified imports with `use ..., only: ...`, rather than merely `use ...`. |
| 38 | +* Prefer importing items used throughout a module with a module-scoped `use` statement, rather than separately in multiple procedures. |
| 39 | +* Use [Doxygen format](https://www.doxygen.nl/manual/docblocks.html#fortranblocks) for docstrings. For dummy arguments, use either `@param ...` above the signature or `!< ...` next to the dummy argument. |
| 40 | +* Name type-bound procedures' first dummy argument `this`. A suitable docstring is `!< this instance`. |
| 41 | +* Avoid deeply nested control structures where possible. |
| 42 | +* Prefer verbose names, except where the meaning is obvious from context or precedent. E.g., well-known index variables (`i`, `j`, `m`, `n`). |
| 43 | +* Use named constants. Avoid [magic numbers](https://en.wikipedia.org/wiki/Magic_number_(programming)). |
| 44 | + |
| 45 | +## Sample Module |
| 46 | + |
| 47 | +Below is a minimal module demonstrating some (but not all) of the conventions. |
| 48 | + |
| 49 | +```f90 |
| 50 | +module SampleModule |
| 51 | +
|
| 52 | + use KindModule, only: DP, I4B, LGP |
| 53 | + use ConstantsModule, only: DPI |
| 54 | +
|
| 55 | + implicit none |
| 56 | + private |
| 57 | + public :: run_sample |
| 58 | +
|
| 59 | +contains |
| 60 | +
|
| 61 | + subroutine run_sample(verbose) |
| 62 | + logical(LGP), intent(in) :: verbose |
| 63 | + integer(I4B) :: answer |
| 64 | + real(DP) :: pi |
| 65 | +
|
| 66 | + answer = 42 |
| 67 | + pi = DPI |
| 68 | +
|
| 69 | + if (verbose) then |
| 70 | + print *, 'pi: ', pi |
| 71 | + print *, 'answer to the ultimate question of life,'& |
| 72 | + ' the universe, and everything: ', answer |
| 73 | + end if |
| 74 | + end subroutine run_sample |
| 75 | +
|
| 76 | +end module SampleModule |
| 77 | +``` |
0 commit comments