Polyglot
Languages MATLAB conditionals
MATLAB § conditionals

Conditionals

Conditional execution in MATLAB is governed by the if keyword. The grammar is conventional — if, elseif, else, end — and the condition is an expression that the language tests for truthiness. The truthiness rule is the principal MATLAB-specific corner: a non-scalar condition is true only when all of its elements are non-zero, which means that the result of an element-wise comparison rarely produces the intended behaviour as an if condition.

Syntax

if condition
    block
elseif other_condition
    block
else
    block
end

The elseif and else clauses are optional; an if with neither is permitted. Conditions are expressions, not statements; assignment is not permitted in a condition (a deliberate departure from C):

x = 5;
if x > 0
    disp("positive")
elseif x < 0
    disp("negative")
else
    disp("zero")
end

There is no if-as-expression form. To choose between two values, the function if-equivalent is the conditional expression via (cond) * a + (~cond) * b or — more idiomatically — through masked assignment, which avoids the conditional altogether.

Truthiness

A condition is true when it is a non-empty array of which every element is non-zero. The rule is the implicit invocation of all(:) over the condition. Specifically:

  • if 0 is false; if 1 is true.
  • if [] is false (empty arrays are not truthy).
  • if [1 1 1] is true.
  • if [1 0 1] is false (one zero element).
  • if "non-empty string" is true (any non-empty string is truthy).

The rule is occasionally surprising: a programmer who writes if A == B expecting a scalar comparison receives a logical array of element-wise comparisons; the array is truthy only if every element matches. The remedy is if isequal(A, B) for whole-array equality and if any(A == B) or if all(A == B) for explicit element-wise tests.

A = [1 2 3];
B = [1 2 3];

if A == B               % logical array [1 1 1]; all true; the block runs.
    disp("equal")
end

A = [1 2 3];
B = [1 2 4];

if A == B               % logical array [1 1 0]; not all true; block skipped.
    disp("equal")       % does not run
end

if isequal(A, B)
    disp("equal")       % does not run; the correct test
end

The recommendation in code that compares arrays is always to use isequal or one of its variants (isequaln, isequalto) for whole-array equality.

Short-circuit vs element-wise

The doubled operators && and || short-circuit and require scalar operands; the single & and | are element-wise. In an if condition the short-circuit forms are usually what is wanted:

% Safe pattern: check that A is non-empty before indexing into it.
if ~isempty(A) && A(1) > 0
    ...
end

% Unsafe: && would short-circuit if isempty(A) was true; & evaluates both,
% and A(1) raises an "index out of bounds" error on an empty A.
if ~isempty(A) & A(1) > 0
    ...
end

The general rule: && and || in conditions and other scalar contexts; & and | for element-wise combination of logical arrays.

The cond ? a : b substitute

MATLAB has no ternary operator. The idiomatic substitutes:

% Two-arm if for scalar values:
if cond
    y = a;
else
    y = b;
end

% Functional via logical indexing (vectorises naturally):
mask = (x > 0);
y = a .* mask + b .* (~mask);     % only meaningful for numeric a, b

% The if-helper "iif" some users write:
iif = @(c, a, b) c * a + (~c) * b;       % works for scalars only

% The function form (R2022b and later):
y = ifelse(cond, a, b);    % returns a if cond, else b — but no longer in base MATLAB

For more involved choices, the switch statement (next page) is the cleaner form.

Guarded computation

A common pattern is to guard a computation that would otherwise produce a warning, an error, or a NaN:

if denominator ~= 0
    r = numerator / denominator;
else
    r = Inf;
end

Element-wise guards combine with logical indexing:

x = [-1 0 1 2 3];
y = nan(size(x));
y(x > 0) = log(x(x > 0));
% y is [NaN NaN 0 0.6931 1.0986]

The masked-assignment form is the idiomatic vector equivalent of “if positive, take the log”.

Validating input

A function commonly guards against invalid arguments. Two styles:

function y = doStuff(x)
    if ~isnumeric(x) || ~isscalar(x)
        error("x must be a numeric scalar")
    end
    y = x^2 + 1;
end

Since R2019b, the arguments validation block is the preferred form for this pattern:

function y = doStuff(x)
    arguments
        x (1, 1) {mustBeNumeric}
    end
    y = x^2 + 1;
end

The block validates at entry and is more readable than a chain of ifs. Argument blocks are covered at length in Functions and scripts.

Why if is sometimes the wrong tool

A reader new to MATLAB writes if-heavy code; a reader experienced in MATLAB writes vectorised code that has no if at all. The principal idiom:

% Idiomatic: vectorised, no if
y = max(0, x);                       % clamp at zero
y = min(max(x, lo), hi);             % clamp to [lo, hi]
y = abs(x);                          % branch-free absolute value

% Less idiomatic but sometimes necessary:
y = x;
y(y < 0) = 0;

A for-loop with an inner if is the slowest of the available forms; logical indexing is fastest and clearest. The if keyword’s most-legitimate use is at the top level of an algorithm — deciding which whole-array operation to perform — not inside an inner loop.