mirror of
https://github.com/status-im/nim-style-guide.git
synced 2025-02-23 03:28:13 +00:00
Updates (#9)
* add section on `string` (fixes #4) * expand `Defect` coverage * expand `CatchableError` coverage (fixes #5) * expand `init` vs `new` * expand formatting of split `if` * avoid `Natural` and other `range` types
This commit is contained in:
parent
eff7ba8660
commit
736711bb19
@ -23,6 +23,7 @@
|
||||
- [Binary data](language.binary.md)
|
||||
- [Integers](language.integers.md)
|
||||
- [`range` types](language.range.md)
|
||||
- [`string`](language.string.md)
|
||||
- [Error handling](errors.md)
|
||||
- [`Result`](errors.result.md)
|
||||
- [Exceptions](errors.exceptions.md)
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
In general, prefer [explicit error handling mechanisms](errors.result.md).
|
||||
|
||||
Annotate each module with a top-level `{.push raises: [Defect].}`.
|
||||
Annotate each module at top-level (before imports):
|
||||
|
||||
* `{.push raises: [Defect].}` (nim 1.2+)
|
||||
* `{.push raises: [].}` (nim 1.6+)
|
||||
|
||||
Use explicit `{.raises.}` annotation for each public (`*`) function.
|
||||
|
||||
@ -71,10 +74,24 @@ raise (ref MyError)(msg: "description", data: value)
|
||||
|
||||
### Practical notes
|
||||
|
||||
The use of exceptions in some modules has significantly contributed to resource leaks, deadlocks and other difficult bugs. The various exception handling proposals aim to alleviate some of the issues but have not found sufficient grounding in the Nim community to warrant the language changes necessary to proceed.
|
||||
The use of exceptions in Nim has significantly contributed to resource leaks, deadlocks and other difficult bugs. The various exception handling proposals aim to alleviate some of the issues but have not found sufficient grounding in the Nim community to warrant the language changes necessary to proceed.
|
||||
|
||||
A notable exception to the guideline is `chronos` and `async`/`await` transformations that lack support for propagating checked exception information. Several bugs and implementation issues exist in the exception handling transformation employed by `async`.
|
||||
|
||||
### `Defect`
|
||||
|
||||
`Defect` does [not cause](https://github.com/nim-lang/Nim/issues/12862) a `raises` effect - code must be manually verified - common sources of Defect include:
|
||||
|
||||
* Over/underflows in signed arithmetic
|
||||
* `[]` operator for indexing arrays/seqs/etc (but not tables!)
|
||||
* accidental/implicit conversions to `range` types
|
||||
|
||||
### `CatchableError`
|
||||
|
||||
Catching `CatchableError` implies that any errors are funnelled through the same exception handler. When called code starts raising new exceptions, it becomes difficult to find affected code - catching more specific errors avoids this maintenance problem.
|
||||
|
||||
Frameworks may catch `CatchableError` to forward exceptions through layers. Doing so leads to type erasure of the actual raised exception type in `raises` tracking.
|
||||
|
||||
### Open questions
|
||||
|
||||
* Should a hierarchy be used?
|
||||
@ -95,4 +112,3 @@ A notable exception to the guideline is `chronos` and `async`/`await` transforma
|
||||
* [Zahary's handling proposal](https://gist.github.com/zah/d2d729b39d95a1dfedf8183ca35043b3) - seeks to handle any kind of error-generating API
|
||||
* [C++ proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0709r0.pdf) - After 25 years of encouragement, half the polled C++ developers continue avoiding exceptions and Herb Sutter argues about the consequences of doing so
|
||||
* [Google](https://google.github.io/styleguide/cppguide.html#Exceptions) and [llvm](https://llvm.org/docs/CodingStandards.html#id22) style guides on exceptions
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
Error handling in Nim is a subject under constant re-evaluation - similar to C++, several paradigms are supported leading to confusion as to which one to choose.
|
||||
|
||||
In part, the confusion stems from the various contexts in which nim can be used: when executed as small, one-off scripts that can easily be restarted, exceptions allow low visual overhead and ease of use.
|
||||
In part, the confusion stems from the various contexts in which Nim can be used: when executed as small, one-off scripts that can easily be restarted, exceptions allow low visual overhead and ease of use.
|
||||
|
||||
When faced with more complex and long-running programs where errors must be dealt with as part of control flow, the use of exceptions can directly be linked to issues like resource leaks, security bugs and crashes.
|
||||
|
||||
Likewise, when preparing code for refactoring, the compiler offers little help in exception-based code: although raising a new exception breaks ABI, there is no corresponding change in the API: this means that changes deep inside dependencies silently break dependent code until the issue becomes apparent at runtime (often under exceptional circumstances).
|
||||
|
||||
A final note is that although exceptions may have been used successfully in some languages, these languages typically offer complementary features that help manage the complexities introduced by exceptions - RAII, mandatory checking of exceptions etc - these have yet to be developed for Nim.
|
||||
A final note is that although exceptions may have been used successfully in some languages, these languages typically offer complementary features that help manage the complexities introduced by exceptions - RAII, mandatory checking of exceptions, static analysis etc - these have yet to be developed for Nim.
|
||||
|
||||
Because of the controversies and changing landscape, the preference for Status projects is to avoid the use of exceptions unless specially motivated, if only to maintain consistency and simplicity.
|
||||
|
||||
|
@ -2,10 +2,14 @@
|
||||
|
||||
Always use the same identifier style (case, underscores) as the declaration.
|
||||
|
||||
Enable `--styleCheck:usages`.
|
||||
|
||||
* `Ref` for `ref object` types, which have surprising semantics
|
||||
* `type XxxRef = ref Xxx`
|
||||
* `type XxxRef = ref object ...`
|
||||
* `type XxxRef = ref Xxx`
|
||||
* `type XxxRef = ref object ...`
|
||||
* `func init(T: type Xxx, params...): T` for "constructors"
|
||||
* `func new(T: type XxxRef, params...): T` for "constructors" of `ref object` types
|
||||
* `func init(T: type ref Xxx, params...): T` when `T` is a `ref`
|
||||
* `func new(T: type Xxx, params...): ref T` for "constructors" that return a `ref T`
|
||||
* `new` introduces `ref` to a non-`ref` type
|
||||
* `XxxError` for exceptions inheriting from `CatchableError`
|
||||
* `XxxDefect` for exceptions inheriting from `Defect`
|
||||
|
@ -14,6 +14,10 @@ We strive to follow [NEP-1](https://nim-lang.org/docs/nep1.html) for style matte
|
||||
func someLongFunctinName(
|
||||
alsoLongVariableName: int) = # Double-indent
|
||||
discard # back to normal indent
|
||||
|
||||
if someLongCondition and
|
||||
moreLongConditions: # Double-indent
|
||||
discard # back to normal indent
|
||||
```
|
||||
|
||||
### Practical notes
|
||||
@ -22,3 +26,4 @@ func someLongFunctinName(
|
||||
* Can break working code
|
||||
* Naive formatting algorithm
|
||||
* We do not make use of Nim's "flexible" identifier names - all uses of an identifier should match the declaration in capitalization and underscores
|
||||
* Enable `--styleCheck:usages`
|
||||
|
@ -6,7 +6,7 @@ Don't use finalizers.
|
||||
|
||||
### Pros
|
||||
|
||||
* Work around missing manual cleanup
|
||||
* Alleviates the need for manual cleanup
|
||||
|
||||
### Cons
|
||||
|
||||
|
@ -16,4 +16,4 @@ Avoid using explicit `{.inline.}` functions.
|
||||
|
||||
* `{.inline.}` does not inline code - rather it copies the function definition into every `C` module making it available for the `C` compiler to inline
|
||||
* Compilers can use contextual information to balance inlining
|
||||
* LTO achieves the same end result without the cons
|
||||
* LTO achieves a similar end result without the cons
|
||||
|
@ -14,7 +14,5 @@ Don't cast pointers to `int`.
|
||||
* Conversion to signed integer raises untracked `Defect` on overflow
|
||||
* When comparing lengths to unsigned integers, convert the length to unsigned
|
||||
* Pointers may overflow `int` when used for arithmetic
|
||||
* An alternative to `int` for non-negative integers such as lengths is `Natural`
|
||||
* `Natural` is a `range` type and therefore [unreliable](#range) - it generally avoids the worst problems owing to its simplicity but may require additional casts to work around bugs
|
||||
* Better models length, but is not used by `len`
|
||||
|
||||
* Avoid `Natural` - implicit conversion from `int` to `Natural` can raise a `Defect`
|
||||
* see [`range`](./language.range.md)
|
||||
|
11
src/language.string.md
Normal file
11
src/language.string.md
Normal file
@ -0,0 +1,11 @@
|
||||
## `string` `[language.string]`
|
||||
|
||||
The `string` type in Nim represents text in an unspecified encoding, typically UTF-8 on modern systems.
|
||||
|
||||
Avoid `string` for binary data (see [language.binary](./language.binary.md))
|
||||
|
||||
### Practical notes
|
||||
|
||||
* The text encoding is undefined for `string` types and is instead determined by the source of the data (usually UTF-8 for terminals and text files)
|
||||
* When dealing with passwords, differences in encoding between platforms may lead to key loss
|
||||
|
@ -1,6 +1,5 @@
|
||||
## Debugging `[tooling.debugging]`
|
||||
|
||||
* Debugging can be done with `gdb`
|
||||
* Follow the [C/C++ guide](https://code.visualstudio.com/docs/cpp/config-linux) for setting it up in `vscode`
|
||||
* Debugging can be done with `gdb` just as if `C` was being debugged
|
||||
* Follow the [C/C++ guide](https://code.visualstudio.com/docs/cpp/cpp-debug) for setting it up in `vscode`
|
||||
* Pass `--opt:none --debugger:native` to disable optimizations and enable debug symbols
|
||||
|
||||
|
@ -18,4 +18,3 @@ We support a single Nim version that is upgraded between release cycles of our o
|
||||
|
||||
* Following Nim `devel`, from experience, leads to frequent disruptions as "mysterious" issues appear
|
||||
* To support multiple Nim versions in a project, the project should be set up to run CI with all supported versions
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user