aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2016-06-08 19:06:29 +0800
committerDeterminant <ted.sybil@gmail.com>2016-06-08 19:06:29 +0800
commitbc49910f6f55620a4fb4e7038e751bab52fdafa6 (patch)
treec8e0c7c12334ab3bc2b49234265eba7e1281e1f2
parent309217c70dcd16d372eaddce8a04e73c9e4e30b8 (diff)
add coding convention
-rw-r--r--nerv/doc/source/coding-convention.rst216
-rw-r--r--nerv/doc/source/collaboration-rules.rst67
2 files changed, 250 insertions, 33 deletions
diff --git a/nerv/doc/source/coding-convention.rst b/nerv/doc/source/coding-convention.rst
index 8e30dea..5826ffc 100644
--- a/nerv/doc/source/coding-convention.rst
+++ b/nerv/doc/source/coding-convention.rst
@@ -1,2 +1,218 @@
Coding Convention
=================
+
+Introduction
+------------
+
+This document stipulates the coding convention for NERV. The convention applies
+to both Lua and C.
+
+Naming
+------
+
+- Variable and function names should only contain lower case alphabets, digits or hyphens.
+
+ - In a local scope, simple names can be used to ease typing:
+
+ .. code-block:: lua
+
+ function a_meaningful_function_name(something)
+ -- "sth" is used to aid typing
+ local sth = something.thing
+ sth.description = "just a trival thing"
+ sth.action = function () end
+ end
+
+ - For global names, meaningful phrases should be used to describe the functionality.
+
+ .. code-block:: lua
+
+ input_size = 429
+ output_size = 3001
+ hidden_size = 2048
+
+ - Use phrasal verbs to describe operations.
+
+ .. code-block:: lua
+
+ function Container:initialize()
+ -- some initialization
+ end
+
+ function Container:append()
+ end
+
+ function Container:get_next()
+ end
+
+ function set_handler()
+ end
+
+- Class names (in Lua) are in "`UpperCamelCase`_".
+
+ .. code-block:: lua
+
+ local mat_cls = nerv.CuMatrixFloat
+ -- keep abberivations in upper case
+ local reader_cls = nerv.HTKReader
+
+.. _`UpperCamelCase`: https://en.wikipedia.org/wiki/CamelCase
+
+Indentation
+-----------
+
+- Four *spaces* are used for one identation level. DO NOT use tabs.
+- Lines should be indented with a nested block:
+
+.. code-block:: lua
+
+ function this_is_a_function(a, b)
+ local sum = 0
+ -- four-space indentation is required here
+ for i = a, b do
+ -- another nested block
+ sum = sum + i
+ end
+ return sum
+ end
+
+Line Breaking
+-------------
+
+- Each line contains 80 characters at most (100 characters when a line is hard
+ to break).
+- DO NOT try to put everything in a single, long line. It would only make your
+ code look stupid and obscure rather than provide with any simplity or
+ elegance.
+- Break long function invocations like this: (make sure the left side of
+ multi-line arguments are aligned and at least one level of indentation is
+ required for each nested invocation)
+
+ .. code-block:: lua
+
+ a_very_very_long_object_name:a_very_very_long_method_name(long_argument1,
+ long_argument2,
+ long_argument3)
+ a_very_very_long_object_name
+ :an_even_longer_version_of_method_name(long_argument1,
+ long_argument2,
+ long_argument3)
+
+ a_very_very_long_object_name:a_very_very_long_method_name(
+ long_argument1,
+ there_is_a_nested_invocation_of_another_function(argument1, argument2)
+ long_argument3,
+ long_argument4)
+
+- Multi-line Lua tables should be like this:
+
+ .. code-block:: lua
+
+ local very_very_very_very_long_table_name = {
+ -- avoid writing the verbose form: ["key"] = value,
+ -- as long as the key is a string
+ key1 = value1,
+ key2 = value2,
+ key3 = value3,
+ key4 = { -- another table
+ k1 = v1,
+ k2 = {
+ even = 1,
+ deeper = 2,
+ tabl = {
+ -- can go deeper
+ }
+ },
+ k3 = {
+ a = 2,
+ b = 3,
+ c = 4
+ },
+ -- short table can be in-line
+ k4 = {a = 1, b = 2, c = 3},
+ [2333] = "number as a key",
+ [{this = 1,
+ is = 2,
+ rare = 3}] = "table as a key"
+ },
+ -- another style of table: write the first key-value
+ -- pair in the same line as "{" and the last pair in
+ -- the same line as "}"
+ key5 = {a = 1,
+ b = 2,
+ c = 3}
+ }
+
+Statements
+----------
+
+- Lua is NOT C, so DO NOT put an extra pair of parentheses in ``if`` statements:
+
+ .. code-block:: lua
+
+ local C = 0
+ local lua = 1
+ -- good style
+ if lua ~= C then
+ print("Lua is not C.")
+ end
+ -- bad style
+ if (lua == C) then
+ print("You seriously?")
+ end
+
+- Try to use Lua-style ``for`` to iterate through all elements:
+
+ .. code-block:: lua
+
+ function get_list(n) -- use closure to make an iterator
+ local i = 0
+ return function ()
+ i = i + 1
+ if i == n then
+ return nil
+ else
+ return i
+ end
+ end
+ end
+
+ local list = { -- emulate an object
+ i = 0,
+ n = 10,
+ get_next = function(self)
+ self.i = self.i + 1
+ if self.i == self.n then
+ return nil
+ else
+ return self.i
+ end
+ end
+ }
+
+ -- good style (for iterators)
+ for e in get_list(10) do
+ print(e)
+ end
+
+ -- good style (for objects)
+ for e in list.get_next, list do
+ print(e)
+ end
+
+ -- bad style
+ local iterate = get_list(10)
+ while true do
+ local e = iterate()
+ if e == nil then break end
+ print(e)
+ end
+
+Remarks
+-------
+
+It is difficult to enumerate all possible code constructs to precisely describe
+the convention. Therefore, when in a doubt, please refer to core NERV and try
+to be consistent with existing code. Also, there is still some code in NERV
+that is not compliant to some of the convention stipulated above, if so, please
+contact the developers.
diff --git a/nerv/doc/source/collaboration-rules.rst b/nerv/doc/source/collaboration-rules.rst
index b7126c9..636c063 100644
--- a/nerv/doc/source/collaboration-rules.rst
+++ b/nerv/doc/source/collaboration-rules.rst
@@ -20,24 +20,24 @@ nature of the tool, our project management is centralized, just like Linux
kernel development which was the original use case of Git. The NERV project, in
a general sense, includes two major sub-projects whose names known as ``nerv`` and
``nerv-speech``, respectively. The former contains the core part of NERV, which
-contains a general deep learning implementation. The latter, ``nerv-speech``
+includes a general deep learning implementation. The latter, ``nerv-speech``,
provides with modules (classes) that comply to the API of core NERV and offer
-supports (such as I/O) that are relevant to speech and language processing
+supports (e.g., for I/O) that are relevant to speech and language processing
(such as reading HTK/Kaldi features and labels).
Like Torch, NERV uses LuaRocks_ to manage optional components as *packages*.
-When running ``make`` in ``nerv`` repository root, LuaRocks and LuaJIT
-(compiler) will be first setup, then a LuaRock package named ``nerv`` will be
-then installed via LuaRocks, which is to say, the core part of NERV is
-contained in a single LuaRocks package, ``nerv``. Next, by invoking ``make
-speech``, several speech processing packages (such as ``htk_io``, ``kaldi_io``,
-etc) will be compiled and installed from ``nerv/speech`` which ought to be
-checked out from ``nerv-speech`` repository. Therefore, thanks to the
-flexibility of Lua and the modularity brought by LuaRocks, new functionalities
-can be added to NERV and managed in a clear way by building a self-contained
-LuaRocks package with possible dependencies on ``nerv`` or other packages. The
-package systems provides with good isolation so that the contributions can be
-better managed and decoupled from core NERV.
+When running ``make`` in ``nerv`` repository root directory, LuaRocks and
+LuaJIT (compiler) will be first setup, then a LuaRock package named ``nerv``
+will then be built and installed via LuaRocks, which is to say, the core part
+of NERV is contained in a single LuaRocks package, ``nerv``. Next, by invoking
+``make speech``, several speech processing packages (such as ``htk_io``,
+``kaldi_io``, etc) will be compiled and installed from ``nerv/speech`` which
+ought to be checked out from ``nerv-speech`` repository. Therefore, thanks to
+the flexibility of Lua and the modularity brought by LuaRocks, new
+functionalities can be added to NERV and managed in a clear way by building
+self-contained LuaRocks packages with possible dependencies on ``nerv`` or other
+packages. The package system provides with good isolation so that the
+contributions can be better managed and decoupled from core NERV.
.. _LuaRocks: https://luarocks.org/
@@ -46,15 +46,16 @@ Isolation v.s. Completeness
The loosely organized nature of Lua and the package manager LuaRocks give us
many possibilities in abstraction and collaboration. However, since no typical
-patterns are really enforced by Lua language, it is impossible to merely hope
-the compiler or interpreter can regulate the implementation by all
+patterns are really enforced by the Lua language, it is impossible to merely
+hope the compiler or interpreter can regulate the implementation by all
contributors. As mentioned in NERV's overview document, one problem of Torch is
it strives to isolate components and wrap them up respectively into different
LuaRocks packages, which is seemingly a good choice for collaboration, however
-not very wise in the long run. The methodology of such "collaboration" means no
-collaboration at all. Under such methodology, each user has the to build
-her/his own package and the reluctance to merge others' code. This leads to
-less and less shared code base and erodes the completeness of a toolkit.
+not very wise in the long run. The methodology of such "collaboration" leads to
+no collaboration at all. Under such methodology, each user has the tendency to
+build her/his own package and the reluctance to merge others' code. This leads
+to less and less shared code base and gradually erodes the completeness of a
+toolkit.
When a new functionality is being added to NERV, there are several approaches,
where each has its merits and demerits. Therefore, here, we describe each
@@ -91,19 +92,19 @@ as the resort.
- which is experimental, so temporarily cannot be merged into NERV (due to
some implementation or stability issues), or
- which is naturally a self-contained or de-coupled extension for NERV (e.g,
- I/O readers)
+ I/O readers), or
- contains modifications or feature enhancements written in not only Lua but
also C/C++ (e.g, efficient data processing or new layer computations).
Please note that making a hybrid LuaRocks package containing C/C++
implementations might be a little difficult for the contributors who are not
very familiar with writing ``Makefile`` or similar C/C++ auto building
- scripts. However, it is extremely easy to write a pure LuaRocks package or to
- convert a above-mentioned modification into a valid package.
+ scripts. However, it is extremely easy to write a LuaRocks package in pure
+ Lua or to convert a above-mentioned Lua modification into a valid package.
-- Making a git *branch* from "master": this measure is usually taken by
- developers or a contributor who knows well about the NERV internals. This
- branching technique can be used under the following circumstances.
+- Creating a git *branch* from "master": this measure is usually taken by
+ developers or contributors who know well about the NERV internals. This
+ branching technique can be used under the following circumstances:
- Core developers make major changes to NERV that can possibly break the
existing functionalities.
@@ -122,19 +123,19 @@ as the resort.
understanding the meaning of each line of code as well as the possible
side-effects, if exist, leave comments to explain.
-- Duplicate the code: this is only for testing or personal use. It is *NOT* a
- way to collaborate or contribute.
+- Copying code: this is only for testing or personal use. It is *NOT* a
+ correct way of collaboration or contribution.
When making a Lua modification or LuaRocks package as mentioned, end users or
-contributors should always keep in mind the following principle:
+contributors should always keep in mind the following principles:
- Try to disentangle the original issue by abstraction.
- Try to consider whether the solution could be generalized to solve others' problems.
- Try to override the default components (implemented by functions, classes) as
"high-level" as possible. For example, when there is an opportunity to
- achieve your goal by hacking a trainer (scheduler), *DO NOT* change
+ achieve your goal by hacking a trainer (scheduler), DO NOT change
implementations for layers or buffers or even CUDA implementation. When there
- is a change of changing one function of a trainer, *DO NOT* re-implement the
+ is a change of changing one function of a trainer, DO NOT re-implement the
whole trainer.
- Try to follow the coding convention in the official code.
@@ -148,7 +149,7 @@ Workflows
functionality:
1. Fork the ``nerv-speech``: make a local branch with a concise name consists
- of only lower case alphadigits or hyphens (regex: ``[a-z][a-z0-9-]*``).
+ of only lower case alphabets, digits or hyphens (regex: ``[a-z][a-z0-9-]*``).
2. Generalize your modifications into a LuaRocks package (naming convention:
``[a-z][a-z0-9_]*``).
@@ -158,7 +159,7 @@ Workflows
Package documents should be located at ``doc`` directory of your
package. All documents should be in plain-text format, however,
human-readable lightweight markup formats are preferred, such as
- Markdown or reStructuredText. *DO NOT* change other directories in
+ Markdown or reStructuredText. DO NOT change other directories in
``nerv-speech``.
4. Commit your changes with a brief but meaningful message. Try to stash your