Although Nim supports a variety of code and formatting styles, it is nevertheless beneficial that certain community efforts, such as the standard library, should follow a consistent set of style guidelines when suitable. This enhancement proposal aims to list a series of guidelines that the standard library should follow.
Note that there can be exceptions to these rules. Nim being as flexible as it is, there will be parts of this style guide that don't make sense in certain contexts. Furthermore, just as Python's style guide changes over time, this style guide will too.
These rules will only be enforced for contributions to the Nim codebase and official projects, such as the Nim compiler, the standard library, and the various official tools such as C2Nim.
# This is bad, as the next time someone comes # to edit this code block, they # must re-align all the assignments again: type WordBool* = int16 CalType* = int ... # 5 lines later CalId* = int LongLong* = int64 LongLongPtr* = ptr LongLong
Note: While the rules outlined below are the current naming conventions, these conventions have not always been in place. Previously, the naming conventions for identifiers followed the Pascal tradition of prefixes which indicated the base type of the identifier - PFoo for pointer and reference types, TFoo for value types, EFoo for exceptions, etc. Though this has since changed, there are many places in the standard library which still use this convention. Such style remains in place purely for legacy reasons, and will be changed in the future.
# Constants can start with either a lower case or upper case letter. const aConstant = 42 const FooBar = 4.2 var aVariable = "Meep" # Variables must start with a lowercase letter. # Types must start with an uppercase letter. type FooBar = object
For constants coming from a C/C++ wrapper, ALL_UPPERCASE are allowed, but ugly. (Why shout CONSTANT? Constants do no harm, variables do!)
type Handle = object # Will be used most often fd: int64 HandleRef = ref Handle # Will be used less often
type UnluckyError = object of Exception
type PathComponent = enum pcDir pcLinkToDir pcFile pcLinkToFile
type PathComponent {.pure.} = enum Dir LinkToDir File LinkToFile
parseUrl
rather than parseURL
, checkHttpHeader
instead of checkHTTPHeader
etc.mitems
or mpairs
(or the now deprecated mget
) that allow a mutating view into some data structure should start with an m
.strutils.replace
an in-place version should get an -In
suffix (replaceIn
for this example).The stdlib API is designed to be easy to use and consistent. Ease of use is measured by the number of calls to achieve a concrete high level action. The ultimate goal is that the programmer can guess a name.
The library uses a simple naming scheme that makes use of common abbreviations to keep the names short but meaningful.
English word | To use | Notes |
---|---|---|
initialize | initT |
init is used to create a value type T
|
new | newP |
new is used to create a reference type P
|
find | find | should return the position where something was found; for a bool result use contains
|
contains | contains | often short for find() >= 0
|
append | add | use add instead of append
|
compare | cmp | should return an int with the < 0 == 0 or > 0 semantics; for a bool result use sameXYZ
|
put | put, []=
|
consider overloading []= for put |
get | get, []
|
consider overloading [] for get; consider to not use get as a prefix: len instead of getLen
|
length | len | also used for number of elements |
size | size, len | size should refer to a byte size |
capacity | cap | |
memory | mem | implies a low-level operation |
items | items | default iterator over a collection |
pairs | pairs | iterator over (key, value) pairs |
delete | delete, del | del is supposed to be faster than delete, because it does not keep the order; delete keeps the order |
remove | delete, del | inconsistent right now |
include | incl | |
exclude | excl | |
command | cmd | |
execute | exec | |
environment | env | |
variable | var | |
value | value, val | val is preferred, inconsistent right now |
executable | exe | |
directory | dir | |
path | path | path is the string "/usr/bin" (for example), dir is the content of "/usr/bin"; inconsistent right now |
extension | ext | |
separator | sep | |
column | col, column | col is preferred, inconsistent right now |
application | app | |
configuration | cfg | |
message | msg | |
argument | arg | |
object | obj | |
parameter | param | |
operator | opr | |
procedure | proc | |
function | func | |
coordinate | coord | |
rectangle | rect | |
point | point | |
symbol | sym | |
literal | lit | |
string | str | |
identifier | ident | |
indentation | indent |
proc repeat(text: string, x: int): string = result = "" for i in 0 .. x: result.add($i)
let
statement (not the var
statement) when declaring variables that do not change within their scope. Using the let
statement ensures that variables remain immutable, and gives those who read the code a better idea of the code's purpose.type LongTupleA = tuple[wordyTupleMemberOne: int, wordyTupleMemberTwo: string, wordyTupleMemberThree: float]
type EventCallback = proc (timeReceived: Time, errorCode: int, event: Event, output: var string) proc lotsOfArguments(argOne: string, argTwo: int, argThree: float argFour: proc(), argFive: bool): int {.heyLookALongPragma.} =
startProcess(nimExecutable, currentDirectory, compilerArguments environment, processOptions)
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/nep1.html