\subsection{Programming Style and Conventions}\label{sec:ProgrammingStyleConventions}

Everyone has their own preferences and style, and the nature of a project such as COMPAS will reflect that. However, there is a need to suggest some guidelines for programming style, naming conventions etc. Following is a description of some of the elements of programming style and naming conventions used to develop COMPAS v2. These may evolve over time.

\subsubsection{Object-Oriented Programming}\label{sec:OOP}

COMPAS is written in C++, an object-oriented programming (OOP) language, and OOP concepts and conventions should apply throughout the code. There are many texts and web pages devoted to understanding C++ and OOP -- following is a brief description of the key OOP concepts:

\paragraph{Abstraction}\label{sec:Abstraction}\mbox{}

\medskip
For any entity, product, or service, the goal of abstraction is to handle the complexity of the implementation by hiding details that don't need to be known in order to use, or consume, the entity, product, or service. In the OOP paradigm, hiding details in this way enables the consumer to implement more complex logic on top of the provided abstraction without needing to understand the hidden implementation details and complexity. (There is no suggestion that consumers shouldn't understand the implementation details, but they shouldn't need to in order to consume the entity, product, or service).

Abstraction in C++ is achieved via the use of \textit{objects} -- an object is an instance of a \textit{class}, and typically corresponds to a real-world object or entity (in COMPAS, usually a star or binary star). An object maintains the state of an object (via class member variables), and provides all necessary means of changing the state of the object (by exposing public class member functions (methods)). A class may expose public functions to allow consumers to determine the value of class member variables (``getters''), and to set the value of class member variables (``setters'').  

\paragraph{Encapsulation}\label{sec:Encapsulation}\mbox{}

\medskip
Encapsulation binds together the data and functions that manipulate the data in an attempt to keep both safe from outside interference and accidental misuse. An encapsulation paradigm that does not allow calling code to access internal object data and permits access through functions only is a strong form of abstraction. C++ allows developers to enforce access restrictions explicitly by defining class member variables and functions as \textit{private}, \textit{protected}, or \textit{public}. These keywords are used throughout COMPAS to enforce encapsulation.

There are very few circumstances in which a consumer should change the value of a class member variable directly (via the use of a setter function) -- almost always consumers should present new situational information to an object (via a public member function), and allow the object to respond to the new information. For example, in COMPAS, there should be almost no reason for a consumer of a star object to directly change (say) the radius of the star -- the consumer should inform the star object of new circumstances or events, and allow the star object to respond to those events (perhaps changing the value of the radius of the star). Changing a single class member variable directly introduces the possibility that related class member variables (e.g. other attributes of stars) will not be changed accordingly. Moreover, developers changing the code in the future should, in almost all cases, expect that the state of an object is maintained consistently by the object, and that there should be no unexpected side-effects caused by calling non class-member functions. In short, changing the state of an object outside the object is potentially unsafe and should be avoided where possible.

\paragraph{Inheritance}\label{sec:Inheritance}\mbox{}

\medskip
Inheritance allows classes to be arranged in a hierarchy that represents \textit{is-a-type-of} relationships. All \textit{non-private} class member variables and functions of the parent (base) class are available to the child (derived) class (and, therefore, child classes of the child class). This allows easy re-use of the same procedures and data definitions, in addition to describing real-world relationships in an intuitive way. C++ allows multiple inheritance -- a class may inherit from multiple parent classes.

Derived classes can define additional class member variables (using the \textit{private}, \textit{protected}, and \textit{public} access restrictions), which will be available to any descendent classes (subject to inheritance rules), but will only be available to ancestor classes via the normal access methods (getters and setters).

\paragraph{Polymorphism}\label{sec:Polymorphism}\mbox{}

\medskip
Polymorphism means \textit{having many forms}. In OOP, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.

Following the discussion above regarding inheritance, in the OOP paradigm, and C++ specifically, derived classes can override methods defined by ancestor classes, allowing a derived class to implement functions specific to its circumstances. This means that a call to a class member function will cause a different function to be executed depending on the type of object that invokes the function. Descendent classes of a class that has overridden a base class member function inherit the overridden function (but can override it themselves).

COMPAS makes heavy use of inheritance and polymorphism, especially for the implementation of the different stellar types.


\subsubsection{Programming Style}\label{sec:ProgrammingStyle}\mbox{}

\medskip
The goal of coding to a suggested style is readability and maintainability -- if many developers implement code in COMPAS with their own coding style, readability and maintainability will be more difficult than if a consistent style is used throughout the code. Strict adherence isn't really necessary, but it will make it easier on all COMPAS developers if the coding style is consistent throughout.

\subparagraph{Comments}\label{sec:Comments}\mbox{}

\medskip
An old, but good, rule-of-thumb is that any file that contains computer code should be about one-third code, one-third comments, and one-third white space. Adhering to this rule-of-thumb just makes the code a bit easier on the eye, and provides some description (at least of the intention) of the implementation.

\subparagraph{Braces}\label{sec:Braces}\mbox{}

\medskip
The placement of braces in C++ code (actually, any code that uses braces to enclose scope) is a contentious issue, with many developers having long-held, often dogmatic preferences.  COMPAS (so far) uses the K\&R style ("the one true brace style") - the style used in the original Unix kernel and Kernighan and Ritchie's book \textit{The C Programming Language}.

The K\&R style puts the opening brace on the same line as the control statement:

\tabto{2em}while (x == y) \lcb \\
\tabto{4em}something(); \\
\tabto{4em}somethingelse(); \\
\rcb

Note also the space between the keyword \textit{while} and the opening parenthesis, surrounding the == operator, and between the closing parenthesis and the opening brace. Spaces here helps with code readability. Surrounding all arithmetic operators with spaces is preferred.

\subparagraph{Indentation}\label{sec:Indentation}\mbox{}

\medskip
There is ongoing debate in the programming community as to whether indentation should be achieved using spaces or tabs (strange, but true{\dots}).  The use of spaces is more common.  COMPAS (so far) has a mix of both -- whatever is convenient (pragmatism is your friend...). Unfortunately a mix of spaces and tabs doesn't work well with some editors - we should settle on one method and try to stick to it.

COMPAS (mostly) uses an indentation size of 4 spaces - again we should settle on a soze and stick to it.

\subparagraph{Function Parameters}\label{sec:FunctionParameters}\mbox{}

\medskip
In most cases, function parameters should be input only -- meaning that the values of function parameters should not be changed by the function. Anything that needs to be changed and returned to the caller should be returned as a functional return. There are a few exceptions to this in COMPAS -- all were done for performance reasons, and are documented in the code.

To avoid unexpected side-effects, developers should expect (in most cases) that any variables they pass to a function will remain unchanged -- all changes should be returned as a functional return.

\subparagraph{Performance \& Optimisation}\label{sec:PerformanceOptimisation}\mbox{}

\medskip
In general, COMPAS developers should code for performance -- within reason. Bear in mind that many functions will be called many, many thousands of times (in some cases, millions) in one execution of the program.  

\begin{itemize}
    \item{Avoid calculating values inside loops that could be calculated once outside the loop.}

    \item{Try to use constants where possible.}

    \item{Use multiplication in preference to functions such as \textit{pow()} and \textit{sqrt()} (note that \textit{pow()} is very expensive computationally; \textit{sqrt()} is expensive, but much less expensive than \textit{pow()}).}

    \item{Don't optimise to the point that readability and maintainability is compromised. Bear in mind that most compilers are good at optimising, and are very forgiving of less-than-optimally-written code (though they are not miracle workers...).}
\end{itemize}

\subsubsection{Naming Conventions}\label{sec:NamingConventions}\mbox{} \\

COMPAS (so far) uses the following naming conventions:
 
\begin{itemize}
    \item{All variable names should be in camelCase -- don't use underscore\_to\_separate\_words.}

    \item{Function names should be in camelCase, beginning with an uppercase letter.  Function names should be descriptive.}

    \item{Class member variable names are prefixed with "m\_", and the character immediately following the prefix should be uppercase (in most cases -- sometimes, for well-known names or words that are always written in lowercase, lowercase might be used).}

    \item{Local variable names are just camelCase, beginning with a lowercase letter (again, with the caveat that sometimes, for well-known names or words that are always written in uppercase, uppercase might be used).}

    \item{Function parameter names are prefixed with ``p\_'', and the character immediately following the prefix should be uppercase (again, with the caveat that sometimes, for well-known names or words that are always written in lowercase, lowercase might be used).}
\end{itemize}
