2014-04-28 19:29:18 +00:00
|
|
|
Nimrod Enhancement Proposal #1 - Standard Library Style Guide
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
========
|
|
|
|
Although Nimrod, through its flexible AST and case-sensitivity settings,
|
|
|
|
supports a variety of code and formatting styles, it is nevertheless beneficial
|
|
|
|
that certain community efforts, such as the standard library, should follow
|
2014-05-23 14:33:36 +00:00
|
|
|
a consistent set of style guidelines when suitable. This enhancement
|
2014-04-28 19:29:18 +00:00
|
|
|
proposal aims to list a series of guidelines that the standard library should
|
|
|
|
follow. Note that these are *guidelines* only. The nature of Nimrod 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
|
2014-05-14 02:12:03 +00:00
|
|
|
[Python's style guide](http://legacy.python.org/dev/peps/pep-0008/) changes
|
2014-04-28 19:29:18 +00:00
|
|
|
over time, this style guide will too.
|
|
|
|
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-04-28 19:29:18 +00:00
|
|
|
Style Guidelines
|
|
|
|
================
|
2014-07-20 02:04:17 +00:00
|
|
|
Spacing and Whitespace Conventions
|
|
|
|
----------------------------------
|
|
|
|
- Lines should be no longer than 80 characters. Limiting the amount of
|
|
|
|
information present on each line makes for more readable code - the reader
|
|
|
|
has smaller chunks to process.
|
|
|
|
|
|
|
|
- 2 spaces should be used for indentation of blocks; tabstops are not allowed
|
|
|
|
(the compiler enforces this). Using spaces means that the appearance of
|
|
|
|
code is more consistant across editors. Unlike spaces, tabstop width varies
|
|
|
|
across editors, and not all editors provide means of changing this width.
|
|
|
|
|
|
|
|
- Use of extra whitespace for alignment in ways other than dictated by the
|
|
|
|
style guide is discouraged. Manual alignment and re-alignment of code is
|
|
|
|
tedious, and not all editors have support for auto-alignment of code
|
|
|
|
sections, plus re-alignment of code blocks causes larger, less distinct
|
|
|
|
code diffs.
|
2014-07-20 02:07:40 +00:00
|
|
|
```nimrod
|
|
|
|
# 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
|
|
|
|
CalId* = int
|
|
|
|
LongLong* = int64
|
|
|
|
LongLongPtr* = ptr LongLong
|
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
|
|
|
|
Naming Conventions
|
|
|
|
------------------
|
|
|
|
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 identifer - 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.
|
2014-04-28 19:29:18 +00:00
|
|
|
|
2014-05-23 14:33:36 +00:00
|
|
|
- Type identifiers should be in CamelCase. All other identifiers should be in
|
2014-05-13 06:37:42 +00:00
|
|
|
pascalCase.
|
2014-05-23 14:33:36 +00:00
|
|
|
```nimrod
|
2014-07-18 21:29:15 +00:00
|
|
|
const aConstant = 42
|
2014-04-28 19:29:18 +00:00
|
|
|
|
2014-07-18 21:29:15 +00:00
|
|
|
var aVariable = "Meep"
|
2014-05-13 06:37:42 +00:00
|
|
|
|
2014-07-18 21:29:15 +00:00
|
|
|
type FooBar = object
|
2014-05-13 06:37:42 +00:00
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
|
|
|
|
|
|
|
- When naming types that come in value, pointer, and reference varieties,
|
|
|
|
use a regular name for the variety that is to be used the most, and add
|
|
|
|
a "Obj", "Ref", or "Ptr" suffix for the other varieties. If there is no
|
|
|
|
single variety that will be used the most, add the suffixes to all versions.
|
|
|
|
```nimrod
|
|
|
|
type
|
|
|
|
handle = int64 # Will be used most often
|
|
|
|
handleRef = ref handle # Will be used less often
|
|
|
|
```
|
|
|
|
<br>
|
|
|
|
|
|
|
|
- Exception and Error types should have the "Error" suffix.
|
|
|
|
```nimrod
|
|
|
|
type unluckyError = object of E_Base
|
|
|
|
```
|
|
|
|
<br>
|
2014-05-13 06:37:42 +00:00
|
|
|
|
2014-07-20 02:04:17 +00:00
|
|
|
- Unless marked with the `{.pure.}` pragma, members of enums should have an
|
|
|
|
identifying prefix, such as an abbreviation of the enum's name. Since
|
|
|
|
non-pure enum members can be referenced without
|
2014-05-23 14:33:36 +00:00
|
|
|
```nimrod
|
2014-05-13 06:37:42 +00:00
|
|
|
type PathComponent = enum
|
|
|
|
pcDir
|
|
|
|
pcLinkToDir
|
|
|
|
pcFile
|
|
|
|
pcLinkToFile
|
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-04-28 19:29:18 +00:00
|
|
|
|
2014-07-20 02:04:17 +00:00
|
|
|
Coding Conventions
|
|
|
|
----------------
|
2014-05-13 06:37:42 +00:00
|
|
|
- The 'return' statement should only be used when it's control-flow properties
|
|
|
|
are required. Use a procedures implicit 'result' variable instead. Using the
|
|
|
|
implicit result variables allows both the Nimrod compiler and its various
|
|
|
|
backends to perform special optimizations
|
|
|
|
|
2014-05-23 14:33:36 +00:00
|
|
|
- Use the 'let' statement (not the var statement) when declaring variables
|
2014-05-13 06:37:42 +00:00
|
|
|
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.
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-05-13 06:37:42 +00:00
|
|
|
|
2014-07-20 02:04:17 +00:00
|
|
|
Conventions for multi-line statements and expressions
|
|
|
|
-----------------------------------------------------
|
2014-05-13 06:37:42 +00:00
|
|
|
- Any tuple type declarations that are longer than one line should use the
|
|
|
|
regular object type layout instead. This enhances the readability of the
|
|
|
|
tuple declaration by splitting its members information across multiple
|
|
|
|
lines.
|
2014-05-23 14:33:36 +00:00
|
|
|
```nimrod
|
2014-05-13 06:37:42 +00:00
|
|
|
type
|
|
|
|
ShortTuple = tuple[a: int, b: string]
|
|
|
|
|
|
|
|
ReallyLongTuple = tuple
|
|
|
|
wordyTupleMemberOne: string
|
|
|
|
wordyTupleMemberTwo: int
|
|
|
|
wordyTupleMemberThree: double
|
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-05-13 06:37:42 +00:00
|
|
|
|
|
|
|
- Similarly, any procedure type declarations that are longer than one line
|
|
|
|
should be formatted in the style of a regular type.
|
2014-05-23 14:33:36 +00:00
|
|
|
```nimrod
|
2014-05-13 06:37:42 +00:00
|
|
|
type
|
|
|
|
EventCallback = proc (
|
|
|
|
timeRecieved: TTime
|
|
|
|
errorCode: int
|
|
|
|
event: Event
|
|
|
|
)
|
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-05-13 06:37:42 +00:00
|
|
|
|
|
|
|
- Multi-line procedure declarations/argument lists should continue on the same
|
2014-05-23 14:33:36 +00:00
|
|
|
column as the opening brace. This style is different from that of procedure
|
|
|
|
type declarations in order to distinguish between the heading of a
|
2014-07-20 02:04:17 +00:00
|
|
|
procedure and its body. If the procedure name is too long to make this style
|
|
|
|
convenient, then one of the styles for multi-line procedure calls (or
|
|
|
|
consider renaming your procedure).
|
2014-05-23 14:33:36 +00:00
|
|
|
```nimrod
|
2014-07-20 02:04:17 +00:00
|
|
|
proc lotsOfArguments(argOne: string, argTwo: int, argThree:float
|
|
|
|
argFour: proc(), argFive:bool): int
|
2014-05-13 06:37:42 +00:00
|
|
|
```
|
2014-07-20 02:04:17 +00:00
|
|
|
<br>
|
2014-04-28 19:29:18 +00:00
|
|
|
|
2014-05-23 14:33:36 +00:00
|
|
|
- Multi-line procedure calls should either have one argument per line
|
|
|
|
(like multi-line type declarations) or continue on the same
|
|
|
|
column as the opening parenthesis (like multi-line procedure declarations).
|
|
|
|
It is suggested that the former style be used for procedure calls with
|
|
|
|
complex argument structures, and the latter style for procedure calls with
|
|
|
|
simpler argument structures.
|
|
|
|
```nimrod
|
|
|
|
# Each argument on a new line, like type declarations
|
|
|
|
# Best suited for 'complex' procedure calls.
|
|
|
|
readDirectoryChangesW(
|
|
|
|
directoryHandle.THandle,
|
|
|
|
buffer.start,
|
|
|
|
bufferSize.int32,
|
|
|
|
watchSubdir.WinBool,
|
|
|
|
filterFlags,
|
|
|
|
cast[ptr dword](nil),
|
|
|
|
cast[POverlapped](ol),
|
|
|
|
cast[LPOverlappedCompletionRoutine](nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Multiple arguments on new lines, aligned to the opening parenthesis
|
|
|
|
# Best suited for 'simple' procedure calls
|
|
|
|
startProcess(nimrodExecutable, currentDirectory, compilerArguments
|
|
|
|
environment, processOptions)
|
2014-07-19 19:13:39 +00:00
|
|
|
```
|