Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update CONTRIBUTING.md #59

Merged
merged 1 commit into from
Sep 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 31 additions & 24 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ We are very happy that you are considering working on algorithm and data structu
- [Readability and naming conventions](#readability-and-naming-conventions)
- [Compilation](#compilation)
- [Types](#types)
- [Result return](#result-return)
- [Exceptions and side-effects](#exceptions-and-side-effects)
- [Documentation, examples and tests](#documentation-examples-and-tests)
- [Other](#other)
Expand All @@ -40,28 +41,28 @@ Being one of our contributors, you agree and confirm that:

We appreciate any contribution, from fixing a grammar mistake in a comment to implementing complex algorithms. Please check the [directory](DIRECTORY.md) and [issues](https://github.com/TheAlgorithms/Nim/issues/) for an existing (or declined) implementation of your algorithm and relevant discussions.

**New implementations** are welcome! This includes: new solutions for a problem, different representations for a data structure, algorithm design with a different complexity or features.
**New implementations** are welcome! This includes new solutions for a problem, different representations for a data structure, and algorithm design with different complexity or features.

**Improving documentation and comments** and **adding tests** is also highly welcome.

**Identical implementations** are not allowed.

### Implementation requirements

- The unit of an implementation we expect is a [**Nim module**](https://nim-lang.org/docs/manual.html#modules). Although the main goals of this repository are educational, the module form mirrors a real world scenario and makes it easy to use the code from this repository in other projects.
- First line must contain the canonical title of the module prefixed by double hashes (`## Title Of The Module`). This title is used in this repository's automation for populating the [Directory](DIRECTORY.md).
- The unit of an implementation we expect is a [**Nim module**](https://nim-lang.org/docs/manual.html#modules). Although the main goals of this repository are educational, the module form mirrors a real-world scenario and makes it easy to use the code from this repository in other projects.
- The first line must contain the canonical title of the module prefixed by double hashes (`## Title Of The Module`). This title is used in this repository's automation for populating the [Directory](DIRECTORY.md).
- The module should be thoroughly documented with doc comments. Follow the [Nim documentation style](https://nim-lang.org/docs/docstyle.html).
- The file begins with the module-level documentation with the general description and explanation of the algorithm/data-structure. If possible, please include:
- The file begins with the module-level documentation with the general description and explanation of the algorithm/data structure. If possible, please include:
* Any restrictions of the implementation and any constraints for the input data.
* An overview of the use-cases.
* An overview of use cases.
* Recommendations for when to use or avoid using it.
* Comparison with the alternatives.
* Links to source materials and further reading.
- Use intuitive and descriptive names for objects, functions, and variables.
- Return all calculation results instead of printing or plotting them.
- This repository is not simply a compilation of *how-to* examples for existing Nim packages and routines. Each algorithm implementation should add unique value. It is fine to leverage the standard library or third-party packages as long as it doesn't substitute writing the algorithm itself. In other words, you don't need to reimplement a basic hash table ([`std/tables`](https://nim-lang.org/docs/tables.html)) each time you need to use it, unless it is the goal of the module.
- Avoid importing third-party libraries. Only use those for complicated algorithms and only if the alternatives of relying on the standard library or including a short amount of the appropriately-licensed external code are not feasible.
- The module has to include tests that check valid and erroneous input values and the appropriate edge-cases. See [Documentation, examples and tests](#documentation-examples-and-tests) below.
- Avoid importing third-party libraries. Only use those for complicated algorithms and only if the alternatives of relying on the standard library or including a short amount of the appropriately licensed external code are not feasible.
- Include tests that cover valid and erroneous input values and the appropriate edge-cases. See [Documentation, examples and tests](#documentation-examples-and-tests) below.

### Nim Coding Style

Expand All @@ -70,39 +71,44 @@ We appreciate any contribution, from fixing a grammar mistake in a comment to im
We want your work to be readable by others; therefore, we encourage you to follow the official [Nim Coding Style](https://nim-lang.org/docs/nep1.html).

- Help your readers by using **descriptive names** that eliminate the need for redundant comments.
- Follow Nim conventions for naming: camelCase for variables and functions, PascalCase for types and objects, PascalCase or UPPERCASE for constants.
- Avoid single-letter variable names, unless it has a minimal lifespan. If your variable comes from a mathematical context or no confusion is possible with another variable, you may use single-letter variables. Generally, single-letter variables stop being OK if there's more than just a couple of them in a scope. Some examples:
- Follow Nim naming conventions: camelCase for variables and functions, PascalCase for types and objects, PascalCase or UPPERCASE for constants.
- Avoid single-letter variable names, unless their lifespan is minimal. If your variable comes from a mathematical context or no confusion is possible with another variable, you may use single-letter variables. Generally, single-letter variables stop being OK if there's more than just a couple of them in a scope. Some examples:
* Prefer `index` or `idx` to `i` for loops.
* Prefer `src` and `dst` to `a` and `b`.
* Prefer `remainder` to `r` and `prefix` to `p`.
- Expand acronyms. Prefer `greatestCommonDivisor()` to `gcd()`, as the former is easier to understand than the latter, especially for non-native English speakers.
- Expand acronyms. For instance, use `greatestCommonDivisor()` rather than `gcd()` for better clarity, especially for non-native English speakers.

#### Compilation

- Compile using the stable version of the Nim compiler. The 2.0 version is not out yet, but it is a good idea to compile against the development version of the compiler to check your implementation is reasonably future-proof.
- The code should successfully compile using the stable version of the Nim compiler. It's a good idea to check compilation against the development version as well for future-proofing.

#### Types

- Use the strictest types possible for the input, output and object fields. Prefer `Natural`, `Positive` or custom [subrange types](https://nim-lang.org/docs/manual.html#types-subrange-types) to unconstrained `int` where applicable, use `Natural` for indexing.
- Use the strictest suitable types for input, output and object fields. Prefer `Natural`, `Positive` or custom [subrange types](https://nim-lang.org/docs/manual.html#types-subrange-types) over unconstrained `int` where applicable, use `Natural` for indexing.
- On the other hand, write generic code where appropriate. Do not impose arbitrary limitations if the code can work on a wider range of data types.
- Don't use unsigned numerical types (`uint` and its sized variants), unless wrapping behaviour or binary manipulation is required for the algorithm.
- Prefer the [`Option[T]`](https://nim-lang.org/docs/options.html) to encode an [optional value](https://en.wikipedia.org/wiki/Option_type) instead of using an invalid value (like the `-1` or an empty string `""`), unless it is critical for the algorithm. It may be also fitting if you are looking for the equivalent of "NULL" (default value for pointers)[^null].

#### Result return

- Prefer the expression-based return over using the implicitly declared `result` variable[^result].
- Use `return` keyword only for changing the control-flow of a function. Minimize such cases.

#### Exceptions and side-effects

- Raise Nim exceptions (`ValueError`, etc.) on erroneous input values.
- Use [exception tracking](https://nim-lang.org/docs/manual.html#effect-system-exception-tracking). Right after the module-level documentation, add a `{.push raises: [].}` module pragma. This enforces that all `func`s don't raise any exceptions. If they do raise at least one, list them all with the `raises` pragma after the return type and before the `=` sign like this: `func foo(bar: int) {.raises: [IOError].} =`.
- Use [exception tracking](https://nim-lang.org/docs/manual.html#effect-system-exception-tracking). Right after the module-level documentation, add a `{.push raises: [].}` module pragma. This enforces that all `func`s do not raise any exceptions. If they do raise at least one, list them all with the `raises` pragma after the return type and before the `=` sign like this: `func foo(bar: int) {.raises: [IOError].} =`.

#### Documentation, examples and tests

- It is incited to give a usage example after the module documentation and the `push raises` pragma in the top-level `runnableExamples` block.
- Use the [`std/unittest` module](https://nim-lang.org/docs/unittest.html) to test your program.
- Consider including a usage example after the module documentation and the `push raises` pragma in the top-level `runnableExamples` block.
- Use the [`std/unittest` module](https://nim-lang.org/docs/unittest.html) to test your code.
- We recommend using a `when isMainModule:` block to run tests. This block runs when the module is compiled as an executable. See the [minimal example](#minimal-example).

#### Other

- If you need a third-party module that is not in the file [third_party_modules.md](https://github.com/TheAlgorithms/Nim/blob/master/third_party_modules.md), please add it to that file as part of your submission.
- Use the export marker `*` to distinguish the functions of your user-facing [application programming interface (API)](https://en.wikipedia.org/wiki/API) from the internal helper functions.
- If you need a third-party module not listed in [third_party_modules.md](https://github.com/TheAlgorithms/Nim/blob/master/third_party_modules.md), please add it to that file as part of your submission.
- Use the export marker `*` to distinguish the functions of your user-facing [application programming interface (API)](https://en.wikipedia.org/wiki/API) from internal helper functions.

### Minimal example

Expand Down Expand Up @@ -134,14 +140,14 @@ when isMainModule:

### Submissions Requirements

- Make sure the code compiles before submitting.
- Look up the name of your algorithm in other active repositories of [TheAlgorithms](https://github.com/TheAlgorithms/), like [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python). By reusing the same name, your implementation will be appropriately grouped alongside other implementations on the [project's web site](https://the-algorithms.com/).
- Please help us keep our issue list small by adding fixes: Add the number of the issue you solved — even if only partially — to the commit message of your pull request.
- Make sure the code [compiles](#compilation) before submitting.
- Look up the name of your algorithm in other active repositories of [TheAlgorithms](https://github.com/TheAlgorithms/), like [TheAlgorithms/Python](https://github.com/TheAlgorithms/Python). By reusing the same name, your implementation will be appropriately grouped alongside other implementations on the [project's website](https://the-algorithms.com/).
- Please help us keep our issue list small by adding fixes: Reference the number of the issue you solved — even if only partially — ino the commit message of your pull request.
- Use *snake_case* (words separated with an underscore `_`) for the filename.
- Try to fit your work into the existing directory structure as much as possible. Please open an issue first if you want to create a new subdirectory.
- Writing documentation, be concise and check your spelling and grammar.
- Add a corresponding explanation to [Algorithms-Explanation](https://github.com/TheAlgorithms/Algorithms-Explanation) (optional but recommended).
- Most importantly, **be consistent in the use of these guidelines**.
- Try to fit your work into the existing directory structure as much as possible. If you want to create a new subdirectory, please open an issue first.
- Writing documentation, be concise and verify your spelling and grammar.
- Optionally but recommended, provide an explanation in [Algorithms-Explanation](https://github.com/TheAlgorithms/Algorithms-Explanation).
- Most importantly, **be consistent in adhering to these guidelines**.

**Happy coding!**

Expand All @@ -150,3 +156,4 @@ when isMainModule:
Authors: [@dlesnoff](https://github.com/dlesnoff), [@Zoom](https://github.com/ZoomRmc).

[^null]: If you are wondering why it's preferable to avoid Null references, you should check [Tony Hoare's report at the QCon 2009 conference](https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/).
[^result]: Refer to comparison of different ways of returning results in [The Status Nim style guide](https://status-im.github.io/nim-style-guide/language.result.html).