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.