Introduction

The goal of this set of coding standards that can be automatically checked is to help you write consistent, clean, understandable and maintainable m-code. The resulting code will be more readable for both yourself and others. These guidelines are no strict rules that must be followed at all cost. They are simply there to help you write m-code well and you can deviate from them as you please.

Automatic compliance checking

The coding standards described here can be checked using Code Checker for MATLAB by MonkeyProof Solutions. These coding standards are configured in the predefined MonkeyProofSolutions configurations set available with the tool. This set is the default selection after installing. For instructions on how to check your code against coding standards, see the video below. The steps are also described below the video.

You can check your code for compliance with the guidelines described here as follows:

  1. Install Code Checker for MATLAB. If you have not purchased the tool yet, you can do so here. Alternatively, you could request a free trial license there.
  2. Open Code Checker for MATLAB in one of two ways:
    • Click the shortcut created at the top of the screen next to the documentation search bar: .
    • Run monkeyproof.cc4m.start() from the command window.
  3. Select whether you want to check one or more files, all files in a folder, or all files in a MATLAB Project.
  4. Select what files/folder/project to check.
  5. Further customization is available, for example checking a folder including or excluding all subfolders.
  6. Click the Run button at the bottom to start checking your code.

The guidelines that require human judgment or are simply not possible to check statically in MATLAB are not part of this coding standard.

Structure of this document

The coding standards and guidelines are grouped under specific categories to help keep things organized:

  • Naming conventions: Guidelines in this chapter describe how variables, functions etc. can be named in a consistent and insightful manner.
  • Layout & comments: This chapter contains guidelines to help improve readability of your code for yourself and for others. There are guidelines on whitespace, comments and more.
  • Statements & expressions: The guidelines and coding standards in this chapter are about how to use constructs such as if/else blocks, what built-in functions or keywords to avoid, how to best structure your statements etc.
  • Higher level guidelines: This chapter contains (among others) coding standards on higher-level objects such as functions or files.

Guideline template

Every guideline is structured as follows:

Guideline name

IDA unique guideline identifier.
TitleBrief description of the guideline.
PriorityPriority of the guideline can be one of Mandatory, Strongly recommended and Recommended. Exactly what each of these means for your case is up to you to decide.
DescriptionA more elaborate description of the guideline. Can include the reasoning behind the guideline: how does your code improve when applying the guideline?
RationaleOne or multiple words describing what the guideline is about. Examples: Readability, Stability.

Avoid:

One or more code examples to avoid using.

Instead use:

The example(s) above improved by complying with the guideline.

Naming conventions

The guidelines in this chapter describe how variables, functions etc. can be named in a consistent and insightful manner. If you wish to deviate from the casing guidelines (for example if you want your variable names snake_cased) at least make sure to apply consistent casing. Use the same casing scheme throughout your code so that classes, functions etc. can be easily identified by their name.

Name length

IDNAMING-1
TitleVariables names shall be at most 32 characters long. Function names shall be at least 3 and at most 32 characters long.
PriorityRecommended
DescriptionNames shall be descriptive, so should not be too short. Names that are too long can reduce readability as well.
RationaleReadability

Avoid:

maximumValueOfTheEntireSetOfDataPoints = max(data);

Instead use:

maxData     = max(data);

Loop iterator naming

IDNAMING-2
TitleIterator variables shall be prefixed with i, j, k etc.
PriorityRecommended
DescriptionIterator variables of for-loops are easily distinguishable from other variables by using these prefixes. Iterator variable names shall be at least 3 characters long. In nested for-loops, the starting letters of the iterator names shall be subsequent letters in the alphabet.
RationaleReadability

Avoid:

for nodeIdx = 1 : 10
    for j = 1 : 3
        myGraph(nodeIdx).plotIt(j);
    end
end

Instead use:

for iNode = 1 : 10
    for jPoint = 1 : 3
        myGraph(iNode).plotIt(jPoint);
    end
end

Negated boolean names

IDNAMING-3
TitleNegated boolean variable names shall be avoided.
PriorityStrongly recommended
DescriptionAvoid variable names including the word not. Readability decreases when variables have negated boolean names.
RationaleReadability

Avoid:

if ~notValid && isNotFound
    error('My error message.')
end

Instead use:

if isValid && ~isFound
    error('My error message.')
end

Parent / child name redundancy

IDNAMING-4
TitleNames of fields and properties shall not contain their parent's name.
PriorityRecommended
DescriptionWhen referenced, the fields and properties can have the same phrase multiple times in a row, which is unnecessary.
RationaleReadability

Avoid:

Beam.beamThickness
chair.weightOfChair

Instead use:

Beam.thickness
chair.weight

Variable casing

IDNAMING-5
TitleVariable names shall be lowerCamelCased.
PriorityMandatory
DescriptionVariable names including acronyms shall be lowerCamelCased.
RationaleReadability

Avoid:

foo_bar = 1;
EggsBenedict = 0;
theHTMLPage = "www.test.com";

Instead use:

fooBar = 1;
eggsBenedict = 0;
theHtmlPage = "www.test.com";

Function casing

IDNAMING-6
TitleUser-defined functions and methods shall be lowerCamelCased.
PriorityMandatory
DescriptionUser-defined functions and methods shall be lowerCamelCased. This excludes a class's constructor.
RationaleReadability

Avoid:

compute_values()
GetBestCandidates()

Instead use:

computeValues()
getBestCandidates()

Class casing

IDNAMING-7
TitleClass names shall be UpperCamelCased.
PriorityMandatory
DescriptionClass names shall be UpperCamelCased (PascalCased).
RationaleReadability

Avoid:

theClassName
other_class_name

Instead use:

TheClassName
OtherClassName

Property casing

IDNAMING-8
TitleProperty names shall be UpperCamelCased.
PriorityMandatory
DescriptionClass property names shall be UpperCamelCased (PascalCased).
RationaleReadability

Avoid:

Chair.armRest
Chair.sell_price

Instead use:

Chair.ArmRest
Chair.SellPrice

Package casing

IDNAMING-9
TitlePackage names shall be lower-cased.
PriorityMandatory
DescriptionPackage names shall be completely lower-cased so they can be easily identified as such.
RationaleReadability

Avoid:

+thePackageName
+another_package

Instead use:

+thepackagename
+anotherpackage

Event casing

IDNAMING-10
TitleEvent names shall be UpperCamelCased.
PriorityMandatory
DescriptionEvent names shall be UpperCamelCased (PascalCased).
RationaleReadability

Avoid:

classdef AmplitudeControl < handle
    events
        buttonPushed
        BUTTON_RELEASED
    end
end

Instead use:

classdef AmplitudeControl < handle
    events
        ButtonPushed
        ButtonReleased
    end
end

Struct field casing

IDNAMING-11
TitleNames of struct fields shall be lowerCamelCased.
PriorityMandatory
DescriptionNames of struct fields shall be lowerCamelCased.
RationaleReadability

Avoid:

circleData.Coordinates
circleData.radius_std

Instead use:

circleData.coordinates
circleData.radiusStd

Constant casing

IDNAMING-12
TitleConstant variable names shall be SCREAMING_SNAKE_CASED.
PriorityMandatory
DescriptionConstant variable names shall be written in all-caps with underscores separating the words.
RationaleReadability

Avoid:

r = 2.86e-23;
base_response = "Hello mr/ms ";

Instead use:

R = 2.86e-23;
BASE_RESPONSE = "Hello mr/ms ";

Enumeration member casing

IDNAMING-13
TitleEnumeration members shall be UpperCamelCased and shall not contain numbers.
PriorityMandatory
DescriptionMembers of an enumeration class shall be UpperCamelCased (PascalCased) and shall not contain numbers.
RationaleReadability

Avoid:

classdef TheClass < handle
    enumeration
        chargingFrom0
        FULL
    end
end

Instead use:

classdef TheClass < handle
    enumeration
        ChargingFromEmpty
        Full
    end
end

Name shadowing

IDNAMING-14
TitleFunctions and variables shall not shadow built-in MATLAB functionality or other code.
PriorityMandatory
DescriptionFunctions and variables shall not shadow built-in MATLAB functionality or other code. This includes MATLAB files (.m, .p, .mlapp, .mlx), mex-files (.mexw32 etc.) and Simulink files (.mdl, .slx)
RationaleNaming

Layout & comments

This chapter contains guidelines to help improve readability of your code for yourself and for others. The guidelines on indentation and whitespace make the code more visually appealing whereas guidelines on comments increase the usability of the code they reference. By using ample whitespace, your code will look clean and the more complicated statements maintain their readability.

Comment blocks

IDLAYOUT-1
TitleComment blocks shall not be used.
PriorityMandatory
DescriptionComment blocks (with %{ notation) shall not be used. Every first comment on a line shall start with a comment indicator (% or ...).
RationaleReadability

Avoid:

%{ This is a comment.
This is also a comment.
%}

Instead use:

% This is a comment.
% This is also a comment.

Function indentation

IDLAYOUT-2
TitleDo not indent functions on the root level of a file.
PriorityStrongly recommended
DescriptionOnly methods in a classdef file and nested functions shall be indented. This allows for shorter lines of code. You can set this as a preference in MATLAB.
RationaleReadability

Avoid:

function computeWeight(in)
    weight = 2 * in;
end

Instead use:

function computeWeight(in)
weight = 2 * in;
end

Whitespace in statements

IDLAYOUT-3
TitleSurround operators with spaces.
PriorityStrongly recommended
DescriptionSurround the following operators with spaces:
= : ^ == <= >= < > ~= & && | || + - * .* /
Do not add a space between the unary minus-sign and its operand.
More whitespace often leads to improved readability.
RationaleReadability

Avoid:

isValid=y>0&&x==-1;

Instead use:

isValid = y > 0 && x == -1;

Whitespace after characters

IDLAYOUT-4
TitleCommas, semicolons and keywords shall be followed by a space unless at the end of the statement.
PriorityStrongly recommended
DescriptionCommas, semicolons and keywords (for, while, if etc.) shall be followed by a space unless at the end of the statement. A clear separation of keywords from other code improves readability.
RationaleReadability

Avoid:

while(ismember(x, [3,5,7,11,13]))
    x = x + 2;
end

Instead use:

while ismember(x, [3, 5, 7, 11, 13])
    x = x + 2;
end

Line length

IDLAYOUT-5
TitleLines shall be no more than 120 characters long.
PriorityStrongly recommended
DescriptionLines shall be no more than 120 characters long, including comments.
A line of code should fit on a screen and a very long line of code can be an indication that the line is too complex.
Use the MATLAB preference for displaying a vertical line at 120 characters.
RationaleReadability

Avoid:

theText = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut luctus arcu ex, at viverra nibh malesuada ac. Proin vel arcu leo.';

Instead use:

theText = ['Lorem ipsum dolor sit amet, consectetur adipiscing elit. ', ...
            'Ut luctus arcu ex, at viverra nibh malesuada ac. Proin vel arcu leo.'];

Indentation length

IDLAYOUT-6
TitleIndentation shall be four spaces long.
PriorityStrongly recommended
DescriptionIndentation shall be four spaces long. This is the default setting in the MATLAB editor.
RationaleReadability

Avoid:

if x > 0
  if x < 2
    disp(x)
  end
end

Instead use:

if x > 0
    if x < 2
        disp(x)
    end
end

Comments on poorly written code

IDLAYOUT-7
TitleComments should not justify poorly written code.
PriorityStrongly recommended
DescriptionDo not use comments to justify or mock poorly written code.
Write proper code that requires no justification instead.
RationaleReadability

Avoid:

x = 2;
y = 3 * x; % TODO: take z into account.

% FIXME: This piece of ugly code is copied from StackExchange.
z=[1,23,8.1]*(x^3.1415)*sqrt(y);

Instead use:

x = 2;
y = 3 * x + z; 

z = [1, 23, 8.1] * (x ^ 3.1415) * sqrt(y);

Equals sign alignment

IDLAYOUT-8
TitleAlign equals signs within a block of assignments.
PriorityRecommended
DescriptionAlign equals signs within the same block of assignments using proper indentation to improve readability.
RationaleReadability

Avoid:

carWeight = 1.7 * 600;
nWheels = 2 + 2;
maximumSpeed = 190;

Instead use:

carWeight       = 1.7 * 600;
nWheels         = 2 + 2;
maximumSpeed    = 190;

Commas in rows

IDLAYOUT-9
TitleUse commas to separate elements in a row.
PriorityRecommended
DescriptionUse commas to separate elements in a row. Place the comma directly after the element.
RationaleReadability

Avoid:

fig.Position    = [0 1000 1.5 130];
saying          = ['An apple a ' period ' keeps the doctor away.'];

Instead use:

fig.Position    = [0, 1000, 1.5, 130];
saying          = ['An apple a ', period, ' keeps the doctor away.'];

Line continuation with operators

IDLAYOUT-10
TitleBinary operators in multi-line statements shall be placed at the start and not at the end of the line.
PriorityRecommended
DescriptionPlace binary operators in multi-line statements at the start and not at the end of the line so that it is clear what the line does.
RationaleReadability

Avoid:

isDone = isImplemented && ...
    isTested && ...
    isDocumented;

Instead use:

isDone = isImplemented ...
    && isTested ...
    && isDocumented;

Methods/Properties blocks with duplicate attributes

IDLAYOUT-11
TitleCombine multiple blocks of properties or methods with equal attributes into one.
PriorityRecommended
DescriptionImprove readability of your classdef files by combining multiple properties and methods blocks with equal attribute values into one. Do not set attributes to their default values.
RationaleReadability

Avoid:

classdef Rocket
    properties (Access = public, Hidden = false, Constant)
        Fuel = "Nuclear"
    end
    
    properties (Constant = true)
        Capacity = 2
    end
end

Instead use:

classdef Rocket
    properties (Constant)
        Fuel = "Nuclear"
        Capacity = 2
    end
end

Statements & expressions

The guidelines in this chapter are about how to use constructs such as if/else blocks, what built-in functions or keywords to avoid or how to best structure your statements. Following these guidelines will ensure the individual statements in your code are complete and easy to read.

Constant definitions at top

IDSTAT-1
TitlePlace constant definitions at the top of the function.
PriorityRecommended
DescriptionConstant definitions shall be placed at the top of the function, after defining global/persistent variables. That way they can easily be found.
RationaleReadability

Avoid:

function testConstants(x)
y = 3 * x;
MAX_Z = 100;
z = min(y, MAX_Z);
end

Instead use:

function testConstants(x)
MAX_Z = 100;

y = 3 * x;
z = min(y, MAX_Z);
end

Magic numbers

IDSTAT-2
TitleDefine and document numeric values as variables before using them in an expression.
PriorityStrongly recommended
DescriptionDo not use magic numbers in your expression. Define them as variables before using them.
This encourages reuse and documentation of numerical constants and improves overall readability.
RationaleReadability, Reusability

Avoid:

for iPick = 1 : 52
    disp(randi(13));
end

Instead use:

DECK_SIZE   = 52;
N_VALUES    = 13;

for iPick = 1 : DECK_SIZE
    disp(randi(N_VALUES));
end

Function calls without inputs

IDSTAT-3
TitleAdd empty parentheses to function calls without input arguments.
PriorityStrongly recommended
DescriptionAdd empty parentheses to function calls without input arguments. This helps to emphasize the fact that they are function calls and not variables or properties.
RationaleReadability

Avoid:

x = rand * 2;

Instead use:

x = rand() * 2;

One statement per line

IDSTAT-4
TitleWrite one statement per line.
PriorityMandatory
DescriptionWrite at most one statement per line to maintain readability.
RationaleReadability

Avoid:

for iNode = 1 : 3, x = x + iNode; disp(x); end

Instead use:

for iNode = 1 : 3
    x = x + iNode;
    disp(x);
end

If else

IDSTAT-5
TitleEvery if shall have an else section.
PriorityStrongly recommended
DescriptionEvery if shall have an else section, even if it does not contain executable code.
That way, no execution paths are overlooked.
RationaleCompleteness, Readability

Avoid:

if x > 0
    saveData()
end

Instead use:

if x > 0
    saveData()
else
    % Do not save data.
end

Switch otherwise

IDSTAT-6
TitleEvery switch shall have an otherwise section.
PriorityStrongly recommended
DescriptionEvery switch shall have an otherwise section, even if it does not contain executable code.
That way, no execution paths are overlooked.
RationaleCompleteness, Readability

Avoid:

switch reply
    case "Yes"
        saveData()
    case "No"
        clearData()
end

Instead use:

switch reply
    case "Yes"
        saveData()
    case "No"
        clearData()
    otherwise
        % Should not get here.
        error("Unknown reply " + reply)
end

Mixed types in expressions

IDSTAT-7
TitleDo not mix operand or operator types in an expression.
PriorityStrongly recommended
DescriptionDo not mix operand or operator types in an expression. For example, do not mix logical and numerical operators in an expression to prevent unexpected results.
RationaleReadability, Robustness

Avoid:

d = a * b && c;

Instead use:

isValid = a * b > 0;
d       = isValid && c;

Parentheses in logical expressions

IDSTAT-8
TitleUse parentheses to clarify precedence in logical expressions.
PriorityStrongly recommended
DescriptionUse parentheses to clarify the precedence of operands in expressions with multiple logical operators. No parentheses are required when only one type of logical operator is used. For example: d = a && b && c;
RationaleReadability

Avoid:

d = a && b || c;

Instead use:

d = (a && b) || c;

Parentheses in mathematical expressions

IDSTAT-9
TitleUse parentheses to clarify precedence in mathematical expressions.
PriorityStrongly recommended
DescriptionUse parentheses to clarify the precedence of operands in expressions with multiple mathematical operators. No parentheses are required when only one type of mathematical operator is used. For example: d = a * b * c;
RationaleReadability

Avoid:

d = a * b + c;
h = f / 2 * g;

Instead use:

d = (a * b) + c;
h = (f / 2) * g;

Assert inputs

IDSTAT-10
TitleEvery assert call shall have an error ID and a message as 2nd and 3rd inputs.
PriorityMandatory
DescriptionEvery call to the built-in assert function shall have an error identifier and a message as second and third inputs.
This ensures proper exception handling.
RationaleTraceability

Avoid:

assert(~isempty(list))

Instead use:

assert(~isempty(list), 'ClassName:MethodName:ListIsEmpty', 'The list shall not be empty.')

Global variables

IDSTAT-11
TitleDo not use global variables.
PriorityMandatory
DescriptionThe value of global variables can change from anywhere, which can make things unnecessarily complicated.
RationaleReadability, Traceability

Constant conditional statements

IDSTAT-12
TitleDo not use conditions like if true and similar.
PriorityStrongly recommended
DescriptionDo not use conditions that are always true or always false such as if true or elseif 0 as they may cause unreachable code or unintented behaviour.
RationaleReadability, Robustness

Avoid:

if x > 0 || true
    disp(x)
end   

Instead use:

disp(x)

Group struct field definitions

IDSTAT-13
TitleAll fields of a struct shall be defined in a single, contiguous block of code.
PriorityStrongly recommended
DescriptionNo fields shall be added to a struct after using it.
RationaleReadability

Avoid:

s = struct("f", 2, "g", 3);

computeCost(s);
s.h = 'new field';

Instead use:

s = struct("f", 2, "g", 3, "h", 'new field');

computeCost(s);

Eval-functions

IDSTAT-14
TitleDo not use the built-in eval. Minimize the use of feval, evalin and evalc.
PriorityStrongly recommended
DescriptionDo not use the built-in eval. Minimize the use of feval, evalin and evalc.
These functions can have harmful results and statements using them are usually difficult to read.
RationaleReadability, Stability

Return keyword

IDSTAT-15
TitleMinimize the use of return.
PriorityMandatory
DescriptionMinimize the use of the return keyword to keep the flow of the code clear.
RationaleReadability

Avoid:

if isempty(x)
    return
end

<rest of the code>

Instead use:

if isempty(x)
    % No further actions.
else
    <rest of the code>
end

Shell escape

IDSTAT-16
TitleDo not use the shell escape function.
PriorityMandatory
DescriptionDo not use the shell escape function. If necessary, use the system function instead.
RationaleCompleteness, Readability

Avoid:

!mycommand

Instead use:

system('mycommand')

Dependencies are known

IDSTAT-17
TitleMake sure all functions called are known.
PriorityMandatory
DescriptionMake sure all functions called are known. Attempting to access packages, classes and functions not on the MATLAB path will result in an error.
RationaleCompleteness, Readability

Try for exception handling

IDSTAT-18
TitleOnly use the try construct for exception handling.
PriorityStrongly recommended
DescriptionOnly use the try construct for exception handling.
An exception object must be assigned or created and an error function must be called in the catch.
Do not use try/catch to suppress errors or to express simple conditions.
There are other, more suitable options for that.
RationaleReadability, Robustness

Avoid:

try
    nElems = container.nElements;
catch
    nElems = 0;
end

Instead use:

if isfield(container, 'nElements')
    nElems = container.nElements;
else
    nElems = 0;
end

Floating-point comparisons

IDSTAT-19
TitleDo not compare floating-point values using == or ~=.
PriorityStrongly recommended
DescriptionDo not compare floating-point values using == or ~=. Rounding errors due to algorithm design or machine precision can cause unexpected results. Use a tolerance instead.
RationaleRobustness

Avoid:

out = myFcn(in) == sqrt(3);

Instead use:

out = abs(myFcn(in) - sqrt(3)) < 1e-12;

Cell arrays

IDSTAT-20
TitleAvoid using cell arrays except for harnessing character arrays or objects of different classes.
PriorityRecommended
DescriptionDo not use cell arrays for anything other than character arrays of objects of different classes.
RationalePerformance, Readability

Avoid:

out = myFcn(in) == sqrt(3);

Instead use:

out = abs(myFcn(in) - sqrt(3)) < 1e-12;

Higher level guidelines

The guidelines in this chapter transcend individual statements. These higher-level guidelines treat things like code complexity and function types.

Complexity

IDFCNS-1
TitleKeep functions short and simple.
PriorityStrongly recommended
DescriptionKeep number of lines of code and cyclomatic complexity to an acceptable level, especially for nested functions and methods in a classdef file. Use the values of the table below.
RationaleReadability, Reusability



Function typeMaximum cyclomatic complexityMaximum number of lines of code
Main20100
Local (Sub)1550
Methods in a classdef1020
Nested510

Number of function arguments

IDFCNS-2
TitleLimit the number of inputs and outputs of a function.
PriorityRecommended
DescriptionLimit the number of inputs and outputs of a function to five. If necessary, combine multiple arguments into a struct. This helps prevent a long calling syntax.
RationaleReadability

Avoid:

out = computeWeight(blockHeight, blockWidth, blockDepth, density, nBlocks, idx);

Instead use:

out = computeWeight(blockData, nBlocks, idx);

Constructors with single output

IDFCNS-3
TitleEvery constructor shall have exactly one output.
PriorityMandatory
DescriptionEvery constructor shall have exactly one output: an object of the class. A second constructor output is unusual, so will be unexpected for readers of the code.
RationaleConsistency

Avoid:

classdef Computer
    methods
        function [obj, out2] = Computer(in)
            obj.value = in;
            out2 = 2 * in;
        end
    end
end

Instead use:

classdef Computer
    methods
        function obj = Computer(in)
            obj.value = in;
        end
    end
end

Scripts

IDFCNS-4
TitleDo not use scripts. Use functions instead.
PriorityRecommended
DescriptionThe scope of variables in a script is not bounded as one might expect. Therefore, use functions even if there are no inputs or outputs.
RationaleScope

Editor warnings

IDFCNS-5
TitlePrevent or suppress Code Analyzer messages.
PriorityStrongly recommended
DescriptionPrevent or suppress Code Analyzer messages shown in the MATLAB editor.
When the messages cannot be prevented, suppress them on an individual basis and add the reason in the comments.
The messages often indicate that improvements can be made to performance or stability of the code.
RationalePerformance, Stability

Avoid:

%#ok<*ABCDE> Suppress a Code Analyzer warning in the entire file.

Instead use:

%#ok<ABCDE> Suppress the Code Analyzer warning on this line alone.

Getters and setters

IDFCNS-6
TitleMinimize the use of Getters and Setters.
PriorityStrongly recommended
DescriptionProperty getters and setters can cause unexpected behaviour because code is run unexpectedly. Write explicit methods for getting or setting if necessary.
RationaleReadability

Mex-files

IDFCNS-7
TitleWhen using a mex-function in your code, make sure versions of the file are available for all platforms.
PriorityMandatory
DescriptionWhen using a mex-function in your code, make sure versions of the file are available for Windows (32 and 64 bit), MacOS and Unix.
RationaleCompatibility

Nesting depth

IDFCNS-8
TitleLimit nesting depth to a maximum of five.
PriorityStrongly recommended
DescriptionDo not nest blocks of code deeper than five levels to maintain readability.
RationaleReadability