Function Precedence and Name Resolution
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Written against MATLAB R2026b. The sessions below were run in GNU Octave 11.3.0 and show Octave’s output; Octave resolves names in a similar way, but the wording of its messages and of which differs from MATLAB’s, so the messages MATLAB prints are "not run here" and are checked against the R2026b documentation.
A name such as sum, heatflow.solve or x can mean a variable, a function in the current file, a function in a folder, a class or a function that was imported. MATLAB resolves it with a fixed order, and the first match wins. Knowing the order explains the classic surprises: a variable that silences a function, a copy of a function in the current folder that replaces the built-in, and a name that means one thing in a script and another in a function. The folders that make up the search path are described on Search Path, Startup and Files, the kinds of function on Functions and Local, Nested and Private Functions, and variables and scope on Workspaces, Scope, Global and Persistent Variables.
The precedence order
When MATLAB meets an identifier it looks for it in this order, and stops at the first match. The list follows the R2026b documentation.
-
Variables. MATLAB looks in the current workspace before it assumes that the name is a function.
-
A function or class whose name matches an explicitly imported name.
importlets a function with a compound name such asheatflow.solvebe called with the last part only; an explicit (non-wildcard) import takes precedence over everything below it. -
Nested functions within the current function.
-
Local functions within the current file.
-
A function or class whose name matches a wildcard import (
import heatflow.*). A wildcard import gives way to nested and local functions. -
Private functions: functions in a subfolder named
privateimmediately below the folder of the running file. -
Object functions: methods that accept a particular class of object. When several have the same name, MATLAB checks the classes of the input arguments to pick one.
-
Loaded Simulink models.
-
Functions in the current folder.
-
Functions elsewhere on the path, in order of appearance.
Figure: the order in which MATLAB resolves a name. Loaded Simulink models, which sit between object functions and the current folder, are left out because they need a product outside base MATLAB.
Three details of the list matter in practice.
-
Position on the path decides, not the kind of file. Up to R2025b a class defined in an
@folder took precedence over functions of the same name regardless of its place on the path. As of R2026a, MATLAB gives precedence by position on the path only (release note quoted from the R2026b page). -
In the same folder, the file type decides. The order is: built-in function, MEX-function, Simulink model files that are not loaded (SLX, then MDL), a Stateflow chart with the
.sfxextension, an App Designer app (.mlapp), a live script or function (.mlx), a P-file (.p), and last a program file (.m). If a folder containssolve.mandsolve.p, MATLAB runs the P-file, and P-files are not regenerated when you edit the.mfile, so regenerate them (pcode) or delete the stale one. -
Static versus run-time. Variables are the first rule, and the R2019b changes below say that identifiers without an explicit declaration might not be treated as variables. That is why code that creates a variable by a means MATLAB cannot see (
eval,loadwithout an output) is a source of surprises; see eval and Its Alternatives.
The R2019b change
Starting in R2019b, MATLAB changed the rules of name resolution, which affects the precedence of variables, nested functions, local functions and external functions. The Function Precedence Order page lists the points of the change; their titles are:
-
identifiers cannot be used for two purposes inside a function;
-
identifiers without an explicit declaration might not be treated as variables;
-
variables cannot be implicitly shared between parent and nested functions;
-
change in the precedence of compound name resolution;
-
anonymous functions can include resolved and unresolved identifiers;
-
the behavior of
importhas changed, including a change in the precedence of wildcard-based imports, fully qualified imports that shadow definitions of the same name in an outer scope, an error when an import is not found, and nested functions that inherit the imports of their parent; -
fully qualified import functions cannot have the same name as nested functions.
In practice: declare a variable before using its name as a function elsewhere in the same function, share data between a function and its nested functions by naming the variable in both, and do not give a variable the same name as a nested or local function. Code written before R2019b that relied on the old rules can raise an error or call a different function; the documentation has a page with tips for updating it. The details are not repeated here because they are reference material for old code, and the page is the authority (link below).
Variables hide functions
The first rule has a consequence that every MATLAB user meets: a variable with the name of a function makes that function unreachable until the variable is cleared. The documentation puts it this way: if you create a variable with the same name as a function, MATLAB cannot run that function until you clear the variable from memory.
x = [1 2 3];
sum(x)
sum = 10;
try
sum(x)
catch err
disp(err.message)
end
exist("sum")
clear sum
sum(x)
exist("sum")
i = 5; z = 2 + 3i
Octave 11.3.0 output:
ans = 6
sum(3): out of bound 1 (dimensions are 1x1) (note: variable 'sum' shadows function)
ans = 1
ans = 6
ans = 5
z = 2 + 3i
sum(x) stopped being a call as soon as sum became a variable: it became an index into the scalar sum, and the error is an indexing error (MATLAB raises an index-out-of-bounds error with the identifier MATLAB:badsubscript; its wording varies by release, not run here). Octave even adds the hint that the variable shadows the function. exist("sum") returns 1 for a variable; after clear sum it returns 5 in Octave (a built-in function). In MATLAB the value after clear sum is 2 or 5 depending on whether the function is a file or a built-in (not run here). The literal 3i still works after i = 5, because 3i is a number and not the name i; 3*i would use the variable.
The usual victims are the names that make good variable names: sum, max, min, mean, size, length, table, string, error, disp, i, j and pi. The cure is to name variables for what they hold (total, maxTemp, plateSize; the heatflow project uses nx, ny and alpha), to call clear name (not clear all, which discards everything and also clears the function cache) when it happens, and to keep the Code Analyzer on (see Code Analyzer and Code Quality), which reports many naming problems in the editor. The pattern in a loop is the classic: for i = 1:n followed later by 3*i that was meant as three times the imaginary unit. Use 1i for the imaginary unit and ii or a descriptive name for indices.
which and which -all
which name reports what a name resolves to and where it comes from, so it is the first tool when a function does not behave as expected. It prints the path of the file that would run, says built-in for a built-in, says that the name is a variable when it is, and which name -all lists every candidate in the order MATLAB would consider them, including the shadowed ones. which also takes an input to resolve methods: the documentation recommends including the function name and the input in the call to which to find which function MATLAB calls for a given input. The shape of the call:
which solve
which solve -all
which("sum")
Output is "not run here" because it contains installation paths; MATLAB prints one path per match. In Octave, which on a variable reports it as such:
sum = 1;
which sum
clear sum
Octave 11.3.0 output: 'sum' is a variable.
Read the output of which -all from top to bottom: the first line is the one that runs, and the other lines are shadowed. A shadowed file is usually the sign of two copies of the same function, a stale copy in the current folder, or a toolbox function whose name a user file repeats. Remove or rename the copy that should not win, or move one of the folders out of the path (see Search Path, Startup and Files). exist("name") returns a number that says what kind of thing a name is (variable, file, built-in, folder) and is the programmatic counterpart.
Source: MATLAB documentation: which
Local, nested and private functions come first
A local function in the same file takes precedence over a function of the same name in another file, including the built-in ones. That is deliberate: it lets one file carry its own helper called norm or validate without disturbing anyone else. The price is the same as for variables: if a file defines a local function with the name of a function it also wants to call, the local one wins silently, and the Code Analyzer and which are the ways to notice. Nested functions come before local functions, and private functions (in private/ below the file’s folder) come after both, so a private helper can be shadowed by a local one with the same name but not by a function elsewhere on the path.
feval follows the same scoping and precedence rules as calling a function handle directly. See Anonymous Functions and Function Handles for handles.
Namespaces and import
A namespace (written as a folder whose name starts with +, for example +heatflow; "package" until R2023b, see Namespaces and Class Folders) groups functions and classes under a prefix, so that two libraries can both have a function called solve: heatflow.solve and poisson.solve. A name with a prefix is a compound name and is always unambiguous. import shortens it:
import heatflow.solve % explicit: solve now means heatflow.solve
import heatflow.* % wildcard: every name in the namespace is available
Not run here (needs the heatflow namespace on the path). The ranks in the list above are the rule: an explicit import is considered right after variables, a wildcard import only after nested and local functions. Two consequences: a wildcard import never hides a nested or local function of the same name, and a fully qualified import cannot have the same name as a nested function. Nested functions inherit the imports of their parent function (both points are in the list of R2019b changes). Because an import changes what a bare name means, prefer the fully qualified call in library code and keep wildcard imports for short scripts.
Source: MATLAB documentation: import
Pitfalls
-
A variable named like a function hides the function until
clear name; the error often looks like an indexing error. -
clear allas a cure also clears functions and breakpoints and makes the next run slower; useclear nameorclearvars. -
A copy of a function in the current folder beats the same name later on the path.
which -allshows the copy. -
A stale P-file beats the
.mfile of the same name in the same folder. -
Scripts and
evalcreating variables that MATLAB cannot see when it parses a function. -
A wildcard
importmakes it hard to tell where a name comes from; the Code Analyzer andwhichshow the answer. -
Relying on pre-R2019b rules: code that used one name for two purposes in a function, or implicitly shared variables with nested functions, may fail or change behavior.
Where older books differ
Older books describe a shorter order (variables, then functions, subfunctions, private functions, then the path) and say nothing about import, namespaces, wildcard imports or the file-type order. The R2019b change and the R2026a change in the treatment of classes in @ folders are newer than the books. The advice about not naming variables after functions is as valid as ever.