Coding Standards
Wherever possible, Arcalibre code should hold to relevant standards and best practices for each language used. In particular:
- Python code should follow PEP 8, and be annotated with correct type information.
- C/C++ code should TODO.
- Rust code should pass
cargo fmtchecks. - JavaScript and TypeScript could should TODO.
General Coding Standards
Warning
Be especially careful when considering example data used in documentation and tests! Bigoted works and works by bigoted authors are not in keeping with the rereading Project Code of Conduct.
Regardless of language, Arcalibre code should always hold to the rereading Project Code of Conduct first and foremost. Identifier names, example data, and code comments should be respectful and professional, and must not be bigoted or otherwise inappropriate.
Where reasonable, Arcalibre code should be annotated with helpful comments that explain not just what code is doing, but why and under what assumptions. Documentation comments in entry points and build recipes should help contributors understand what to run, when, and why.
Naming Conventions
Irrespective of language, and when it does not contradict per-language conventions, Arcalibre code should follow a few naming conventions:
- If a function or method does not cause side effects, use a noun or adjective phrase as its name; similarly, functions and methods which do cause side effects should use verb phrases for their names.
- Function, method, and property names that are part of an interface should never use proper names of people.
Python Coding Standards
Naming and Formatting
Python code should follow PEP 8 style rules, especially those rules that relate to naming functions, classes, variables, and other identifiers:
- Variables, functions, properties, and other identifiers that do not represent types should be named in all lowercase, using
snake_case. - Classes and other identifiers used as the names of types should be named as
CamelCase, so as to be clearly distinguishable from non-types.
There are always edge cases; for example, in some cases, a type that's intended to be used as a function may be named in snake_case instead. These edge cases should be rare, however, and violating PEP 8 should be an intentional decision made for a specific reason.
Module and Package Interfaces
The interfaces for modules and packages should be kept as narrow as reasonable, so as to avoid creating unintended interdependencies between different modules. Avoid using from X import * whenever reasonable, and use leading underscores to denote functions and classes that are not intended to be part of the public interface for a module or package.
Data Types
Where possible and reasonable, avoid relying on data types with interior mutability across function and method boundaries. For example, prefer frozen dataclasses to namedtuples when reasonable.
Where possible and reasonable, prefer data types that can be clearly documented and understood, even at the cost of verbosity. For example, dataclasses allow annotating types and adding documentation comments to each field, and should be preferred to namedtuples when reasonable.
Class and type hierarchies should be shallow when reasonable --- inheritance introduces a kind of nonlocality that can make it difficult to trace functionality across modules and packages. Inheritance is quite useful, but works best when used judiciously.
Documentation Strings
TODO: document docstring formats once we have an API reference pipeline.