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.

  1. Variables. MATLAB looks in the current workspace before it assumes that the name is a function.

  2. A function or class whose name matches an explicitly imported name. import lets a function with a compound name such as heatflow.solve be called with the last part only; an explicit (non-wildcard) import takes precedence over everything below it.

  3. Nested functions within the current function.

  4. Local functions within the current file.

  5. A function or class whose name matches a wildcard import (import heatflow.*). A wildcard import gives way to nested and local functions.

  6. Private functions: functions in a subfolder named private immediately below the folder of the running file.

  7. 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.

  8. Loaded Simulink models.

  9. Functions in the current folder.

  10. Functions elsewhere on the path, in order of appearance.

flowchart TD N["Identifier in code, for example sum"] --> V{"Variable with this name in the current workspace?"} V -- yes --> RV["Use the variable"] V -- no --> I{"Explicitly imported name?"} I -- yes --> RI["Use the imported function or class"] I -- no --> NL{"Nested or local function of this name?"} NL -- yes --> RNL["Use that nested or local function"] NL -- no --> W{"Wildcard-imported name?"} W -- yes --> RW["Use the imported function or class"] W -- no --> P{"Private function in the private subfolder?"} P -- yes --> RP["Use the private function"] P -- no --> O{"Object function, chosen by the class of the arguments?"} O -- yes --> RO["Call the method"] O -- no --> C{"File in the current folder?"} C -- yes --> RC["Use the file in the current folder"] C -- no --> PA{"File on the search path?"} PA -- yes --> RPA["Use the first one on the path"] PA -- no --> ERR["Error: unrecognized function or variable (MATLAB:UndefinedFunction)"]

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 .sfx extension, an App Designer app (.mlapp), a live script or function (.mlx), a P-file (.p), and last a program file (.m). If a folder contains solve.m and solve.p, MATLAB runs the P-file, and P-files are not regenerated when you edit the .m file, 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, load without 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 import has 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.

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.

Pitfalls

  • A variable named like a function hides the function until clear name; the error often looks like an indexing error.

  • clear all as a cure also clears functions and breakpoints and makes the next run slower; use clear name or clearvars.

  • A copy of a function in the current folder beats the same name later on the path. which -all shows the copy.

  • A stale P-file beats the .m file of the same name in the same folder.

  • Scripts and eval creating variables that MATLAB cannot see when it parses a function.

  • A wildcard import makes it hard to tell where a name comes from; the Code Analyzer and which show 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.