Skip to content

Coding Standards

Mark Rogoyski edited this page Sep 10, 2019 · 19 revisions

PSR Standards

MathPHP follows the following PSR coding standards:

There are two exceptions to PSR-12 coding style:

  • Camel case method names is followed, but with the exception for mathematical function names that use Greek letters, such as γ and Γ. However, these are only acceptable for internal usage as they reduce visual complexity of large formulas. They are not acceptable for public API methods.
  • Line length limit of 80 characters is not enforced. We live in an age with HD wide screen monitors. It is OK to go beyond 80 characters, but keep it reasonable.

Here is the coding standard configuration for PHPCS.

Style Guide

Variable Names

Use descriptive variable names. Where applicable, use concise mathematical symbols that match the equation or formula being implemented.

For example, if you were computing variance:

prefer: σ² = $∑⟮xᵢ − μ⟯² / $ν;

to: $variance = $sum_of_squared_deviations_x_against_mean / $degrees_of_freedom;

MathPHP is a modern PHP library and makes use of Unicode. There is no reason to limit variable names to the 26 English letters. Just make sure that all variables and equations are fully documented so the variable names are clear when they come up.

However, public user-facing names such as API method names and keys of arrays returned from methods should use standard English ASCII text names.

For general descriptive names, use $snake_case_with_underscores.

When mathematical custom has a variable name that is commonly used, use that if it is reasonable to do so. For example, $A to represent a matrix.

Method Names

Use lowerCamelCase.

Treat initialisms as words when formatting as lowerCamelCase.

Examples:

  • luDecomposition
  • isRref
  • pdf

Code in Paragraphs

Code in paragraphs. Related code will go together in a block like a paragraph. When the focus changes, add an extra newline and start a new block (a new paragraph).

Example:

public function someFunction(int $a, int $b)
{
    // Validate inputs (Validation block)
    if ($a < 0) {
      throw new \Exception('A must be >= 0');
    }
    if ($b == 0) {
      throw new \Exception ('B must not == 0');
    }

    // Use XYZ method to compute e (Computation block)
    $c = $a + b;
    $d = $c + $a + 9;
    $e = $c + d;

    // (Final block)
    return $e;
}

Note: In real code you would use better descriptions of the code blocks.

Line up code

Code that is visually aligned has less visual complexity, and is easier to comprehend. Where applicable, format code so things are lined up.

Example of unaligned code (bad):

$x = 12;
$x2 = 5;
$sum = $x + $x2;

Example of aligned code (good):

$x   = 12;
$x2  = 5;
$sum = $x + $x2;

Type declarations

Use type declarations for method parameters and return values. When type hinting a class, use the most generic interface or parent/abstract class if appropriate.

If there is ambiguity if a number may be a float or an int, use float.

PHPDocBlock Method Documentation

All methods will be documented with PHPDocBlock. Each method must include the method name, a brief description of the method, a formula or equation if appropriate, explanation of the formula, equation, or method used, and document any parameters, return value, and exceptions. If applicable, provide citations if referenced.

/**
 * Method name
 *
 * Description of the method.
 * (link to citation)
 *
 * (Equation)
 * x = y
 *
 * @param int $x Description of parameter
 * @param int $y Description of parameter
 *
 * @return int
 * @throws Exception if x > b
 */
public function sum(int $x, int $y): int

Learn more about PHPDocBlock

General Documentation

Formulas and Equations

Document formulas, equations, and methods used to implement mathematical calculations and methods, etc. Document them in the method's PHPDocBlock. Use formal math notation with English explanations. Explain what each variable is.

Provide links or formal citations for algorithms, equations, formulas, etc. This is a math library--there is nothing original here. Documentation of what formula or method is used allows the user to learn more about the math involved, and verify that methods do what they are supposed to do.

Unit Tests

Unit tests should have three basic sections:

  • Given - Setup or initial conditions
  • When - The subject under test is executed
  • Then - The expected result of the subject under test is checked

Furthermore, use a data provider to thoroughly test many kinds of inputs and outputs.

/**
 * @test         add
 * @dataProvider dataProviderForAddition
 * @param        float $a
 * @param        float $b
 * @param        float $expectedSum
 */
public function testAddition(float $a, float $b, float $expectedSum)
{
    // Given
    $adder = new Adder();

    // When
    $sum = $adder->add($a, $b);

    // Then
    $this->assertEquals($expectedSum, $sum);
}

/**
 * @return array [a, b, sum]
 */
public function dataProviderForAddition(): array
{
    return [
        [0, 1, 1],
        [1, 1, 2],
        [4, 8, 12],
        [55.4, 12.4, 67.8],
        // .. more test cases
    ];
}