```@meta
CurrentModule = Nemo
CollapsedDocStrings = true
DocTestSetup = Nemo.doctestsetup()
```

# Conventions

AbstractAlgebra and Nemo have adopted a number of conventions to help maintain
a uniform codebase.

## Code conventions

### Function and type names

Names of types in Julia follow the convention of CamelCase where the first
letter of each word is capitalised, e.g. `Int64` and `AbstractString`.

Function/method names in Julia use all lowercase with underscores between
the words, e.g. `zip` and `jacobi_symbol`.

We follow these conventions in Nemo with some exceptions:

* When interfacing C libraries the types use the same spelling and
  capitalisation in Nemo as they do in C, e.g. the FLINT library's `ZZPolyRingElem`
  remains uncapitalised in Nemo.

* Types such as `fpPolyRingElem` which don't exist under that name on the C side
  also use the lowercase convention as they wrap an actual C type which must be
  split into more than one type on the Julia side. For example `zzModPolyRingElem` and
  `fpPolyRingElem` on the Julia side both represent FLINT `zzModPolyRingElem`'s on the C side.

* Types of rings and fields, modules, maps, etc. are capitalised whether they
  correspond to a C type or not, e.g. `fqPolyRepField` for the type of an
  object representing the field that `fqPolyRepFieldElem`'s belong to.
.
* We omit an underscore if the first word of a method is "is" or "has", e.g.
  `iseven`.

* Underscores are omitted if the method name is already well established
  without an underscore in Julia itself, e.g. `setindex`.

* Constructors with the same name as a type use the same spelling and
  capitalisation as that type, e.g. `ZZRingElem(1)`.

* Functions for creating rings, fields, modules, maps, etc. (rather than the
  elements thereof) use CamelCase, e.g. `polynomial_ring`. We refer to these 
  functions as parent constructors. Note that we do not follow the Julia
  convention here, e.g. `polynomial_ring` is a function and not a type constructor
  (in fact we often return a tuple consisting of a parent object and other
  objects such as generators with this type of function) yet we capitalise it.

* We prefer words to not be abbreviated, e.g. `denominator` instead of `den`.

* Exceptions always exist where the result would be offensive in any major
  spoken language (example omitted).

It is easy to find counterexamples to virtually all these rules. However we
have been making efforts to remove the most egregious cases from our codebase
over time. As perfect consistency is not possible, work on this has to at
times take a back seat.

### Use of ASCII characters

All code and printed output in Nemo should use ASCII characters only. This is
because we have developers who are using versions of the WSL that cannot
correctly display non-ASCII characters.

This extends to function and operator names, which saves people having to
learn how to enter them to use the system.

### Spacing and tabs

All function bodies and control blocks should be indented using spaces.

A survey of existing code shows 2, 3 or 4 space indenting commonly used in our
files. Values outside this range should not be used.

When contributing to an existing file, follow the majority convention in that
file. Consistency within a file is valued highly.

If you are new to Nemo development and do not already have a very strong
preference, new files should be started with 3 space indenting. This maximises
the likelihood that copy and paste between files will be straightforward, though
modern editors ease this to some degree.

Function signatures in docstrings should have four spaces before them.

Where possible, line lengths should not exceed 80 characters.

We use a term/factor convention for spacing. This means that all (additive)
terms have spaces before and after them, (multiplicative) factors usually do
not.

In practice this means that `+`, `-`, `=`, `==`, `!=`, `<`, `>`, `<=`, `>=` all
have spaces before and after them. The operators `*`, `/`, `^` and unary minus
do not.

As per English, commas are followed by a single space in expressions. This
applies for example to function arguments and tuples.

We do not put spaces immediately inside or before parentheses.

Colons used for ranges do not have spaces before or after them.

Logical operators, `&`, `|`, `&&`, etc. usually have spaces before and after
them.

### Comments

Despite appearances to the contrary, we now prefer code comments explaining the
algorithm as it proceeds.

The hash when used for a comment should always be followed by a space. Full
sentences are preferred.

We do not generally use comments in Nemo for questions, complaints or
proposals for future improvement. These are better off in a ticket on GitHub
with a discussion that will be brought to the attention of all relevant
parties.

Any (necessary) limitations of the implementation should be noted in
docstrings.

### Layout of files

In Nemo, all types are places in special files with the word "Types" in their
name, e.g. `FlintTypes.jl`. This is because Julia must be aware of all types
before they are used. Separation of types from implementations makes it easy
to ensure this happens.

Most implementation files present functions in a particular order, which is as
follows:

* A header stating what the file is for, and if needed, any copyright notices

* Functions applying to any "types" used in the file, e.g. `parent_type`,
  `elem_type`, `base_ring`, `parent`, `check_parent`.

* Basic manipulation, including hashes, predicates, getters/setters, functions
  for creating special values (e.g. `one`, `zero` and the like),
  `deepcopy_internal`. These are usually fairly short functions, often a single
  line.

* Indexing (`getindex`, `setindex`), iteration, views.

* String I/O (`expressify` and file access, etc.)

* Arithmetic operations, usually in multiple sections, such as unary
  operations, binary operations, ad hoc binary operations (e.g. multiplication
  of a complex object by a scalar), comparisons, ad hoc comparisons, division,
  etc.

* More complex functionality separated into sections based on functionality
  provided, e.g. gcd, interpolation, special functions, solving, etc.

* Functions for mapping between different types, coercion, changing base ring,
  etc.

* Unsafe operators, e.g. `mul!`, `add!`, etc.

* Random generation

* Promotion rules

* Parent object call overload (e.g. for implementing `R(2)` where `R` is an
  object representing a ring or field, etc.)

* Additional constructors, e.g. `matrix`, which might be used instead of a
  parent object to construct elements.

* Parent object constructors, e.g. `polynomial_ring`, etc.

The exact order within the file is less important than generally following
something like the above. This aids in finding functions in a file since all
files are more or less set out the same way.

For an example to follow, see the `src/Poly.jl` and `src/generic/Poly.jl` files
in AbstractAlgebra which form the oldest and most canonical example.

Headings for sections should be 80 characters wide and formed of hashes in the
style that can be seen in each Nemo file.

