Best practices - nim-lang/Nim GitHub Wiki

Best Practices

This list is a community-maintained guide for some "best practice" suggestions. Written in the TLDR style, suggestions are in no particular order, should be beneficial to users with any level of Nim proficiency.

  • Use 2-spaces indentation.
  • Use func where possible.
  • Use auto instead of any.
  • Use self instead of this for specifying the main object argument in routines.
  • Use const and let where possible.
  • Put your types near the top of the file.
  • Use import for public code instead of include.
  • Use include for unittesting private code instead of import.
  • Use runnableExamples for code examples in the documentation.
  • Use tuple to return multiple values of different types.
  • Standard library imports should be prefixed with std/, like std/os, std/[strutils, sequtils], etc.
  • Use when isMainModule: to specify code that'll only run if the source file is the main one.
  • Design your code to work in-place, then use sugar.dup if you need to call it out-of-place.
  • Prefer in-place functions, for example, sort instead of sorted where appropriate.
  • Use options for optional types and optional returns.
  • Use Natural or Positive as an argument or input type for non-negative integers.
  • Use char to operate on single characters, for example "foo" & '\n' instead of "foo" & "\n".
  • Annotating routines with {.deprecated.} will make the compiler print out all places where that routine is called.
  • Procedures like echo, repr, astToStr, assert, expandMacros and the compiler switch --expandArc can be useful for debugging.
  • In macros prefer to operate on the AST instead of using parseStmt and string operations.
  • For designing new macros write the desired result manually and then use dumpAstGen to get macro code that will generate the same code.
  • Use string to represent strings of any kind (Nim strings are not encoded in any way) - NOT for binary blobs.
  • Use seq[byte] to represent raw binary blobs.
  • Prefer to use func and/or proc even for OOP, use interface-like libraries (for example iface instead of method unless there's no way around it.
  • Use nimble init or a "repo template" like nimtemplate to start a new project.
  • Try to use FIXME, NOTE, OPTIMIZE, TODO in relevant code comments so that editors and GitHub Actions can read them.
  • For documentation it is generally preferred to use descriptive third person present tense with proper punctuation.
  • For documentation the first paragraph of a doc comment must be a summary, it should concisely define the purpose and functionality of the module/library.
  • Do NOT use distinct tuple.
  • Do NOT use float for things that need to be precise (like money), instead consider using decimal.
  • Do NOT use discard on a Future.
  • Do NOT add label names to the block statement if you don't use them.
  • Do NOT write error messages in ALL_CAPS.
  • Do NOT use exclamation marks in error messages.
  • Do NOT name your variables in ALL_CAPS unless it's required for FFI purposes.
  • Do NOT use Natural or Positive as a return type for integers, use int or uint instead.
  • Do NOT use try blocks with a lot of except branches, use explicit control flow instead.
  • Do NOT repeat & too much for string concatenation, use add instead.
  • Do NOT repeat & too much to string formatting, use std/strformat instead.
  • Do NOT call randomize() in your libraries that use std/random, users should call it themselves.

See also: