Octave style guide: Difference between revisions
m (Remove recommendation for fixed line length) |
m (→Indentation) |
||
(21 intermediate revisions by the same user not shown) | |||
Line 13: | Line 13: | ||
There is no fixed line length. In general, strive for clarity and readability and use your own judgement. | There is no fixed line length. In general, strive for clarity and readability and use your own judgement. | ||
Everyone has access to monitors with more than 80 columns, but even so, exceptionally long lines can be hard to read. | Everyone has access to monitors with more than 80 columns, but even so, exceptionally long lines can be hard to read. However, keeping code together on a line that is logically one unit does improve readability. | ||
=== Indentation === | === Indentation === | ||
Line 19: | Line 19: | ||
Use only spaces, and indent 2 spaces at a time. | Use only spaces, and indent 2 spaces at a time. | ||
Absolutely '''do not use tabs''' in your code. You should probably set your editor to emit spaces when you hit the tab key. | |||
You should probably set your editor to emit spaces when you hit the tab key. | |||
=== Whitespace === | === Whitespace === | ||
===== Function Calls ===== | |||
When calling functions, put spaces after commas and before the calling | When calling functions, put spaces after commas and before the calling | ||
Line 38: | Line 39: | ||
Here, putting spaces after {{codeline|sin}}, {{codeline|cos}} would result in a | Here, putting spaces after {{codeline|sin}}, {{codeline|cos}} would result in a | ||
parse error. | parse error. | ||
===== Indexing Expressions ===== | |||
For indexing expressions, do ''not'' put a space after the | For indexing expressions, do ''not'' put a space after the | ||
Line 49: | Line 52: | ||
<pre>A([1:i-1;i+1:n], XI(:,2:n-1))</pre> | <pre>A([1:i-1;i+1:n], XI(:,2:n-1))</pre> | ||
===== Matrix Definition ===== | |||
When constructing matrices, prefer using the comma rather than the space to | When constructing matrices, prefer using the comma rather than the space to | ||
Line 58: | Line 63: | ||
</pre> | </pre> | ||
However, if the matrix is large or the indentation makes it clear the comma | However, if the matrix is large or the indentation makes it clear then the comma | ||
may be dropped. | may be dropped. | ||
Line 65: | Line 70: | ||
44.04 55.05 6.06]; | 44.04 55.05 6.06]; | ||
</pre> | </pre> | ||
There is no need to include semicolons to define rows when a newline is used instead. | |||
===== Arithmetic Operators ===== | |||
Do include spaces around all binary arithmetic operators, for example | Do include spaces around all binary arithmetic operators, for example | ||
Line 72: | Line 81: | ||
</pre> | </pre> | ||
An exception is for extremely simple expressions like <pre>n+1</pre> | An exception is for extremely simple expressions like | ||
particular | |||
expression. For example, you may write | <pre>n+1</pre> | ||
In particular, simple expressions used as an argument to a function or as part of an indexing expression usually look better without extra spacing. For example, you may write | |||
<pre> | <pre> | ||
Line 80: | Line 91: | ||
</pre> | </pre> | ||
Another exception is for complex arithmetic expressions. It may improve | Another exception is for complex arithmetic expressions. It ''may'' improve readability to omit spaces around higher precedence operators, for example | ||
readability to omit spaces around higher precedence operators, for example | |||
<pre> | <pre> | ||
Line 91: | Line 101: | ||
When you encounter an error condition, call the function {{codeline|error}} | When you encounter an error condition, call the function {{codeline|error}} | ||
(or {{codeline|print_usage}}). The {{codeline|error}} and {{codeline|print_usage}} functions | (or {{codeline|print_usage}}). The {{codeline|error}} and {{codeline|print_usage}} functions | ||
do not return. | do not return. | ||
with the name of the function that generated it. For example: | |||
It is customary to prefix the error message with the name of the function that generated it. For example: | |||
<pre>error ("my_cool_function: input A must be a matrix");</pre> | <pre>error ("my_cool_function: input A must be a matrix");</pre> | ||
Octave has several functions that produce error messages according | Because the function call to {{codeline|error}} is one code unit, prefer keeping the message on one line even if the message itself is long. | ||
to the Octave guidelines. Consider using {{codeline|inputParser}} | |||
Octave has several functions that produce error messages according to the Octave guidelines. Consider using {{codeline|inputParser}} | |||
and {{codeline|validateattributes}}. | and {{codeline|validateattributes}}. | ||
== Naming == | == Naming == | ||
Use lowercase names if possible. Uppercase is acceptable for variable | Use lowercase names if possible. Uppercase is acceptable for variable names consisting of 1-2 letters. Do not use mixed case (a.k.a. CamelCase) names. | ||
names consisting of 1-2 letters. Do not use mixed case names. | |||
names must be lowercase. Function names are global, so choose them | Function names must be lowercase. Function names are global, so choose them wisely. | ||
wisely. | |||
=== General naming functions === | === General naming functions === | ||
Line 111: | Line 122: | ||
=== Function names === | === Function names === | ||
For most public functions we are limited by Matlab compatibility. Use | For most public functions we are limited by Matlab compatibility. Use whatever name Matlab chose. | ||
whatever name Matlab | |||
For functions that are not present in Matlab, favor the use of underscores. | |||
For example, {{codeline|base64_decode}}, {{codeline|common_size}}, or {{codeline|compare_versions}}. | |||
There are exceptions to this: | |||
; Matching C functions | ; Matching C functions | ||
Line 126: | Line 137: | ||
Avoid reusing the names of other functions as local variable names. For | Avoid reusing the names of other functions as local variable names. For | ||
example, | example, avoid naming local variables {{codeline|abs}}, | ||
{{codeline|log}}, or {{codeline|pow}}. These | {{codeline|log}}, or {{codeline|pow}}. These names might be used later to try to call the function of that name, but instead will refer to a local variable, leading to very confusing errors. | ||
An exception is the use of {{codeline|i}} and {{codeline|j}} as loop indices. | An exception is the use of {{codeline|i}} and {{codeline|j}} as loop indices. | ||
Line 198: | Line 208: | ||
=== # or % === | === # or % === | ||
Always use {{Codeline|#}} to write comments. | Always use {{Codeline|#}} to write comments for Octave code. Only use {{Codeline|%}} if code must run in a dual Matlab/Octave environment. | ||
Absolutely do not use {{codeline|%#}} or mix {{codeline|%}} and {{codeline|#}} | Absolutely do not use {{codeline|%#}} or mix {{codeline|%}} and {{codeline|#}} |
Latest revision as of 21:49, 20 December 2023
A lot of GNU Octave is written in the Octave language itself. This document details the Octave style used by the GNU Octave project.
Being part of the GNU project, Octave inherits the GNU coding standards. However, those were written with C in mind and can't always apply to Octave code.
See also the GNU Octave C++ style guide.
Formatting[edit]
Line Length[edit]
There is no fixed line length. In general, strive for clarity and readability and use your own judgement.
Everyone has access to monitors with more than 80 columns, but even so, exceptionally long lines can be hard to read. However, keeping code together on a line that is logically one unit does improve readability.
Indentation[edit]
Use only spaces, and indent 2 spaces at a time.
Absolutely do not use tabs in your code. You should probably set your editor to emit spaces when you hit the tab key.
Whitespace[edit]
Function Calls[edit]
When calling functions, put spaces after commas and before the calling parentheses, like this:
x = max (sin (y + 3), 2);
An exception are matrix or cell constructors:
[sin(x), cos(x)] {sin(x), cos(x)}
Here, putting spaces after sin
, cos
would result in a
parse error.
Indexing Expressions[edit]
For indexing expressions, do not put a space after the identifier (this differentiates indexing and function calls nicely). The space after a comma is not necessary if index expressions are simple, i.e., you may write
A(:,i,j)
but
A([1:i-1;i+1:n], XI(:,2:n-1))
Matrix Definition[edit]
When constructing matrices, prefer using the comma rather than the space to distinguish between columns.
M = [1, 2, 3 4, 5, 6];
However, if the matrix is large or the indentation makes it clear then the comma may be dropped.
prices = [ 1.01 2.02 3.03 44.04 55.05 6.06];
There is no need to include semicolons to define rows when a newline is used instead.
Arithmetic Operators[edit]
Do include spaces around all binary arithmetic operators, for example
x = 1 / (1 + y) ^ 2;
An exception is for extremely simple expressions like
n+1
In particular, simple expressions used as an argument to a function or as part of an indexing expression usually look better without extra spacing. For example, you may write
x(1:end-1)
Another exception is for complex arithmetic expressions. It may improve readability to omit spaces around higher precedence operators, for example
z = cat (dim, (x2.*y3 - x3.*y2), (x3.*y1 - x1.*y3), (x1.*y2 - x2.*y1));
Error messages[edit]
When you encounter an error condition, call the function error
(or print_usage
). The error
and print_usage
functions
do not return.
It is customary to prefix the error message with the name of the function that generated it. For example:
error ("my_cool_function: input A must be a matrix");
Because the function call to error
is one code unit, prefer keeping the message on one line even if the message itself is long.
Octave has several functions that produce error messages according to the Octave guidelines. Consider using inputParser
and validateattributes
.
Naming[edit]
Use lowercase names if possible. Uppercase is acceptable for variable names consisting of 1-2 letters. Do not use mixed case (a.k.a. CamelCase) names.
Function names must be lowercase. Function names are global, so choose them wisely.
General naming functions[edit]
Function names[edit]
For most public functions we are limited by Matlab compatibility. Use whatever name Matlab chose.
For functions that are not present in Matlab, favor the use of underscores.
For example, base64_decode
, common_size
, or compare_versions
.
There are exceptions to this:
- Matching C functions
- If the function exists elsewhere with a common name, use it. For example,
dup2
,waitpid
,printf
,argv
, orgetopt
. - Matching similar functions
- If there are similarly named functions, consider using same style. For example,
fftconvn
andhistthresh
, match the naming offftconv2
andgraythresh
.
Variable names[edit]
Avoid reusing the names of other functions as local variable names. For
example, avoid naming local variables abs
,
log
, or pow
. These names might be used later to try to call the function of that name, but instead will refer to a local variable, leading to very confusing errors.
An exception is the use of i
and j
as loop indices.
If a function has nothing to do with complex arithmetic, it is common and
acceptable to use i
and j
as local variables in
for loops.
Quoted Strings[edit]
Always use double quotes for strings and characters rather than the Matlab single quote convention. Both quote types are accepted by Octave, but double quoted strings are interpreted slightly differently (see Strings in the manual for details).
Do:
a = "Hello, world"; b = "x"; disp ("This \"string\" contains a\nnewline");
Don't:
s = 'Hello, world'; if (x(1) == 'c') disp ('Don''t quote one character this way, even if you''re a C programmer'); endif
There are a few edge cases where single quoted strings may be preferable, and are permitted as exceptions under this style guide.
- String containing double quotes
- A string that contains many double quote characters itself, where escaping all of them with backslashes becomes inconvenient, may be easier with single quotes.
- String containing backslashes
- A string that contains literal backslashes, in particular a regular expression pattern, where doubly escaping certain character sequences is both inconvenient and harder to read, is usually better done with single quotes.
- Argument interpreted differently
- A string argument to the regexp family of functions may be interpreted differently depending on whether it is a double quoted or single quoted string. Certain escape sequences are interpreted only in a single quoted string for Matlab compatibility.
ending blocks[edit]
Always use a specific end-of-block statement (like endif
,
endswitch
) rather than the generic end
.
Enclose the condition of an if
, while
, until
, or
switch
statement in parentheses, as in C:
if (isvector (a)) s = sum (a); endif
Do not do this, however, with the iteration counter portion of a for
statement. Write:
for i = 1:n b(i) = sum (a(:,i)); endfor
! operator[edit]
- The Octave operator
!
should be used for logical negation, rather than~
. - The negation operator is written with a space between the operator and its target, e.g.,
! A
. - For comparisons use
!=
instead of~=
.
Comments[edit]
# or %[edit]
Always use #
to write comments for Octave code. Only use %
if code must run in a dual Matlab/Octave environment.
Absolutely do not use %#
or mix %
and #
in the same file.
Block and Inline comment[edit]
Use a single #
for inline comments. Use double ##
for block comments.
Comments that start with a single sharp-sign, #
, are used to explain
the code on the same line as the comment itself. These comments should
all be aligned to the same column to the right of the source code. In
the Emacs mode for Octave, the M-;
(@code{indent-for-comment})
command automatically inserts such a #
in the right place, or
aligns such a comment if it is already present. Example:
C = 2 * pi * r; # formula for circumference of a circle
Comments that start with a double sharp-sign, ##
, are stand-alone
comments that occupy an entire line. These comments should be aligned to
the same level of indentation as the code. Such comments usually
describe the purpose of the following lines or the state of the program
at that point. Example:
## Calculate area and volume of a sphere A = 4 * pi * r^2; V = 4/3 * pi * r^3;
Commenting out code[edit]
Do not comment code out. If the code is no longer used, remove it. We use version control, we can always bring it back.
%! for test and demo blocks[edit]
Any demos or Built-In Self Tests (BIST) using the %!demo
or
%!test
syntax should begin two lines after the endfunction
keyword. Demo blocks should be listed before test blocks.
See the section Writing tests on the Tests page.
FIXME notes[edit]
The preferred comment mark for places that may need further attention is
with FIXME:
comments.