Switch and dispatch
MATLAB does not have pattern matching in the algebraic sense — there is no decomposing destructuring of values into constructors and bound names. It does, however, have a switch statement that dispatches on a scalar value through a sequence of case branches. The construct is convenient for finite enumerations, mode strings, and the dispatch of small finite state machines; it is appreciably more readable than a chain of elseif clauses.
switch syntax
switch expr
case value1
block1
case value2
block2
case {value3a, value3b} % cell — matches any of the values
block3
otherwise
defaultBlock
end
The expression is evaluated once; each case value is compared to it with isequal-like semantics (numerical or string equality, no type coercion). The first matching branch is executed; control then falls out of the switch — there is no fall-through and no break is needed or permitted.
A cell argument to case matches when the expression equals any of the cell’s elements; it is the most-used MATLAB shortcut for the “or” case.
function speed = describe(mode)
switch mode
case "fast"
speed = "quick";
case {"medium", "default"}
speed = "normal";
case "slow"
speed = "leisurely";
otherwise
error("Unknown mode: %s", mode)
end
end
The otherwise branch is optional but is the conventional place to raise an error or to set a default; falling out of a switch without matching is silently OK.
Scalar dispatch only
MATLAB’s switch matches with equality and dispatches on a scalar expression. There is no:
- range matching (
case 1..10), - type matching (
case Integer), - destructuring (
case (x, y)), - guard clauses (
case x when x > 0), - regular-expression matching.
Each of these patterns has a MATLAB idiom — if/elseif, isa, deconstruct-by-assignment, regexp — but the switch is not the place for them. For tagged-union style dispatch, the conventional approach is switch class(x) plus dispatch by class name; for state-machine style code, switch state plus reassignment.
A finite state machine
The canonical use of switch is a small state machine:
function transition(state, event)
switch state
case "idle"
switch event
case "start"
state = "running";
case "configure"
state = "configuring";
end
case "running"
switch event
case "stop"
state = "idle";
case "fault"
state = "error";
end
case "error"
if event == "reset"
state = "idle";
end
end
end
The doubly nested switch is the most-idiomatic MATLAB way to express the transitions; for larger state machines the Stateflow toolbox is the recommended alternative.
Switching on class
A canonical pattern in functions that accept multiple input classes is switch class(x):
function describe(x)
switch class(x)
case "double"
fprintf("double of size %s\n", mat2str(size(x)))
case "single"
fprintf("single of size %s\n", mat2str(size(x)))
case "char"
fprintf("char string: %s\n", x)
case "string"
fprintf("string scalar: %s\n", x)
case "cell"
fprintf("cell of length %d\n", numel(x))
otherwise
fprintf("class: %s\n", class(x))
end
end
The dispatch is convenient and is clearer than a chain of isa(x, ...) tests. For function dispatch on class — the OO-style polymorphism — classdef methods provide the cleaner mechanism (see Classes and OOP).
Why no destructuring
MATLAB’s value model is array-based: a value is an array of a single class, possibly nested through cells and structs. Algebraic destructuring requires either tagged unions (which MATLAB does not have natively) or types as patterns (which MATLAB’s switch does not support). The closest MATLAB has is the comma-separated-list expansion [a, b, c] = deal(...) — a multiple-return assignment that names the elements of an expanded list:
[m, n] = size(A);
[Q, R] = qr(A);
[V, D] = eig(A);
s = struct('x', 1, 'y', 2, 'z', 3);
[x, y, z] = deal(s.x, s.y, s.z); % three separate scalars
c = {1, "two", [3 4 5]};
[a, b, d] = c{:}; % brace expansion into LHS
These forms are not pattern matching; they are multiple assignment, with the right-hand side already producing N separate values. They cover the most common need: “this thing has known structure; give me the parts in named variables”.
A note on try/catch as dispatch
For dispatch by kind of failure — when the question is “did this raise an error of a specific class?” — the try/catch construct (covered on Error handling) is the appropriate mechanism. The ME.identifier is a colon-separated string that can be examined or matched with regexp. The convention is for the catch block to be a small bit of dispatch logic, not a full pattern match.
A note on regular expressions
Where another language would write a pattern match against a structured string, MATLAB writes a regexp:
[tokens, match] = regexp("name: Ada Lovelace; year: 1815", ...
'name: (\w+) (\w+); year: (\d+)', ...
'tokens', 'match', 'once');
% tokens = {'Ada', 'Lovelace', '1815'}
% match = "name: Ada Lovelace; year: 1815"
For text-extraction-as-pattern-match, regexp with 'tokens' and 'names' is the canonical mechanism; for typed pattern matching on structured data, no mechanism exists in the base language.