| Products & Services | Industries | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → MATLAB |
| Contents | Index |
| Learn more about MATLAB |
| On this page… |
|---|
Variable Scope in Nested Functions Using Function Handles with Nested Functions |
You can define one or more functions within another function in your MATLAB application. These inner functions are said to be nested within the function that contains them. You can also nest functions within other nested functions. You cannot however define a nested function inside any of the MATLAB program control statements. This includes any block of code that is controlled by an if, else, elseif, switch, for, while, try, or catch statement.
To write a nested function, simply define one function within the body of another function in an M-file. Like any M-file function, a nested function contains any or all of the components described in Basic Parts of an M-File in the Programming Fundamentals documentation. In addition, you must always terminate a nested function with an end statement:
function x = A(p1, p2) ... function y = B(p3) ... end ... end
Note M-file functions don't normally require a terminating end statement. This rule does not hold, however, when you nest functions. If an M-file contains one or more nested functions, you must terminate all functions (including subfunctions) in the M-file with end, whether or not they contain nested functions. |
This example shows function A and two additional functions nested inside A at the same level:
function x = A(p1, p2) ... function y = B(p3) ... end function z = C(p4) ... end ... end
This example shows multiply nested functions, C nested inside B, and B in A:
function x = A(p1, p2)
...
function y = B(p3)
...
function z = C(p4)
...
end
...
end
...
endYou can call a nested function
From the level immediately above it. (In the following code, function A can call B or D, but not C or E.)
From a function nested at the same level within the same parent function. (Function B can call D, and D can call B.)
From a function at any lower level. (Function C can call B or D, but not E.)
function A(x, y) % Primary function
B(x, y);
D(y);
function B(x, y) % Nested in A
C(x);
D(y);
function C(x) % Nested in B
D(x);
end
end
function D(x) % Nested in A
E(x);
function E(x) % Nested in D
...
end
end
endYou can also call a subfunction from any nested function in the same M-file.
You can pass variable numbers of arguments to and from nested functions, but you should be aware of how MATLAB interprets varargin, varargout, nargin, and nargout under those circumstances. See "Passing Optional Arguments to Nested Functions" in the MATLAB Programming Fundamentals documentation for more information on this.
Note If you construct a function handle for a nested function, you can call the nested function from any MATLAB function that has access to the handle. See Using Function Handles with Nested Functions. |
Nested functions are not accessible to the str2func or feval function. You cannot call a nested function using a handle that has been constructed with str2func. And, you cannot call a nested function by evaluating the function name with feval. To call a nested function, you must either call it directly by name, or construct a function handle for it using the @ operator.
The scope of a variable is the range of functions that have direct access to the variable to set, modify, or acquire its value. When you define a local (i.e., nonglobal) variable within a function, its scope is normally restricted to that function alone. For example, subfunctions do not share variables with the primary function or with other subfunctions. This is because each function and subfunction stores its variables in its own separate workspace.
Like other functions, a nested function has its own workspace. But it also has access to the workspaces of all functions in which it is nested. So, for example, a variable that has a value assigned to it by the primary function can be read or overwritten by a function nested at any level within the primary. Similarly, a variable that is assigned in a nested function can be read or overwritten by any of the functions containing that function.
In the following two examples, variable x is stored in the workspace of the outer varScope function and can be read or written to by all functions nested within it.
function varScope1 | function varScope2 |
As a rule, a variable used or defined within a nested function resides in the workspace of the outermost function that both contains the nested function and accesses that variable. The scope of this variable is then the function to which this workspace belongs, and all functions nested to any level within that function.
In the next example, the outer function, varScope3, does not access variable x. Following the rule just stated, x is unknown to the outer function and thus is not shared between the two nested functions. In fact, there are two separate x variables in this example: one in the function workspace of nestfun1 and one in the function workspace of nestfun2. When nestfun2 attempts to update x, it fails because x does not yet exist in this workspace:
function varScope3
nestfun1
nestfun2
function nestfun1
x = 5;
end
function nestfun2
x = x + 1
end
end
Variables containing values returned by a nested function are not in the scope of outer functions. In the two examples shown here, the one on the left fails in the second to last line because, although the value of y is returned by the nested function, the variable y is local to the nested function, and unknown to the outer function. The example on the right assigns the return value to a variable, z, and then displays the value of z correctly.
Incorrect | Correct |
|---|---|
function varScope4 y | function varScope5 z |
Every function has a certain scope, that is, a certain range of other functions to which it is visible. A function's scope determines which other functions can call it. You can call a function that is out of scope by providing an alternative means of access to it in the form of a function handle. (The function handle, however, must be within the scope of its related function when you construct the handle.) Any function that has access to a function handle can call the function with which the handle is associated.
Note Although you can call an out of scope function by means of a function handle, the handle itself must be within the scope of its related function at the time it is constructed. |
The section on Calling Nested Functions defines the scope of a nested function. As with other types of functions, you can make a nested function visible beyond its normal scope with a function handle. The following function getCubeHandle constructs a handle for nested function findCube and returns its handle, h, to the caller. The @ sign placed before a function name (e.g., @findCube) is the MATLAB operator that constructs a handle for that function:
function h = getCubeHandle
h = @findCube; % Function handle constructor
function cube = findCube(X) % Nested function
cube = X .^ 3;
end
endCall getCubeHandle to obtain the function handle to the nested function findCube. Assign the function handle value returned by getCubeHandle to an output variable, cubeIt in this case:
cubeIt = getCubeHandle;
You can now use this variable as a means of calling findCube from outside of its M-file:
cubeIt(8)
ans =
512Note When calling a function by means of its handle, use the same syntax as if you were calling a function directly. But instead of calling the function by its name (e.g., strcmp(S1, S2)), use the variable that holds the function handle (e.g., fhandle(S1, S2)). |
One characteristic of nested functions that makes them different from other MATLAB functions is that they can share nonglobal variables with certain other functions within the same M-file. A nested function nFun can share variables with any outer function that contains nFun, and with any function nested within nFun. This characteristic has an impact on how certain variables are stored when you construct a handle for a nested function.
Defining Variables When Calling Via Function Handle. The example below shows a primary function getHandle that returns a function handle for the nested function nestFun. The nestFun function uses three different types of variables. The VLoc variable is local to the nested function, VInp is passed in when the nested function is called, and VExt is defined by the outer function:
function h = getHandle(X) h = @nestFun; VExt = someFun(X); function nestFun(VInp) VLoc = 173.5; doSomeTask(VInp, VLoc, VExt); end end
As with any function, when you call nestFun, you must ensure that you supply the values for any variables it uses. This is a straightforward matter when calling the nested function directly (that is, calling it from getHandle). VLoc has a value assigned to it within nestFun, VInp has its value passed in, and VExt acquires its value from the workspace it shares with getHandle.
However, when you call nestFun using a function handle, only the nested function executes; the outer function, getHandle, does not. It might seem at first that the variable VExt, otherwise given a value by getHandle, has no value assigned to it in the case. What in fact happens though is that MATLAB stores variables such as VExt inside the function handle itself when it is being constructed. These variables are available for as long as the handle exists.
The VExt variable in this example is considered to be externally scoped with respect to the nested function. Externally scoped variables that are used in nested functions for which a function handle exists are stored within the function handle. So, function handles not only contain information about accessing a function. For nested functions, a function handle also stores the values of any externally scoped variables required to execute the function.
The sCountFun and nCountFun functions shown below return function handles for subfunction subCount and nested function nestCount, respectively.
These two inner functions store a persistent value in memory (the value is retained in memory between function calls), and then increment this value on every subsequent call. subCount makes its count value persistent with an explicit persistent declaration. In nestCount, the count variable is externally scoped and thus is maintained in the function handle:
Using a Subfunction | Using a Nested Function |
|---|---|
function h = sCountFun(X) | function h = nCountFun(X) |
When sCountFun executes, it passes the initial value for count to the subCount subfunction. Keep in mind that the count variable in sCountFun is not the same as the count variable in subCount; they are entirely independent of each other. Whenever subCount is called via its function handle, the value for count comes from its persistent place in memory.
In nestCount, the count variable again gets its value from the primary function when called from within the M-file. However, in this case the count variable in the primary and nested functions are one and the same. When nestCount is called by means of its function handle, the value for count is assigned from its storage within the function handle.
Running the Example. The subCount and nestCount functions increment a value in memory by another value that you pass as an input argument. Both of these functions give the same results.
Get the function handle to nestCount, and initialize the count value to a four-element vector:
h = nCountFun([100 200 300 400]) count = 100 200 300 400
Increment the persistent vector by 25, and then by 42:
h(25) count = 125 225 325 425 h(42) count = 167 267 367 467
Now do the same using sCountFun and subCount, and verify that the results are the same.
Note If you construct a new function handle to subCount or nestCount, the former value for count is no longer retained in memory. It is replaced by the new value. |
The code shown below constructs two separate function handles to the same nested function, nestCount, that was used in the last example. It assigns the handles to fields counter1 and counter2 of structure s. These handles reference different instances of the nestCount function. Each handle also maintains its own separate value for the externally scoped count variable.
Call nCountFun twice to get two separate function handles to nestCount. Initialize the two instances of count to two different vectors:
s.counter1 = nCountFun([100 200 300 400]); count = 100 200 300 400 s.counter2 = nCountFun([-100 -200 -300 -400]); count = -100 -200 -300 -400
Now call nestCount by means of each function handle to demonstrate that MATLAB increments the two count variables individually.
Increment the first counter:
s.counter1(25) count = 125 225 325 425 s.counter1(25) count = 150 250 350 450
Now increment the second counter:
s.counter2(25) count = -75 -175 -275 -375 s.counter2(25) count = -50 -150 -250 -350
Go back to the first counter and you can see that it keeps its own value for count:
s.counter1(25) count = 175 275 375 475
The scoping rules for nested, and in some cases anonymous, functions require that all variables used within the function be present in the text of the M-file code. Adding variables to the workspace of this type of function at run time is not allowed.
MATLAB issues an error if you attempt to dynamically add a variable to the workspace of an anonymous function, a nested function, or a function that contains a nested function. Examples of operations that might use dynamic assignment in this way are shown in the table below.
Type of Operation | How to Avoid Using Dynamic Assignment |
|---|---|
Evaluating an expression using eval or evalin, or assigning a variable with assignin | As a general suggestion, it is best to avoid using the eval, evalin, and assignin functions altogether. |
Loading variables from a MAT-file with the load function | Use the form of load that returns a MATLAB structure. |
Assigning to a variable in a MATLAB script | Convert the script to a function, where argument- and result-passing can often clarify the code as well. |
Assigning to a variable in the MATLAB debugger | You can declare the variable to be global. For example, to create a variable X for temporary use in debugging, use K>> global X; X = value |
One way to avoid this error in the other cases is to pre-declare the variable in the desired function.
This section shows a few examples of how you can use nested functions. These examples are intended to show you how to program with this type of function. For more mathematically oriented examples, see the MATLAB Mathematics documentation.
The examples in this section include
The following example constructs a function handle for a nested function and then passes the handle to the MATLAB fplot function to plot the parabola shape. The makeParabola function shown here constructs and returns a function handle fhandle for the nested parabola function. This handle gets passed to fplot:
function fhandle = makeParabola(a, b, c) % MAKEPARABOLA returns a function handle with parabola % coefficients. fhandle = @parabola; % @ is the function handle constructor function y = parabola(x) y = a*x.^2 + b*x + c; end end
Assign the function handle returned from the call to a variable (h) and evaluate the function at points 0 and 25:
h = makeParabola(1.3, .2, 30)
h =
@makeParabola/parabola
h(0)
ans =
30
h(25)
ans =
847.5000Now pass the function handle h to the fplot function, evaluating the parabolic equation from x = -25 to x = +25:
fplot(h, [-25 25])

The fact that a function handle separately maintains a unique instance of the function from which it is constructed means that you can generate multiple handles for a function, each operating independently from the others. The function in this example makes IIR filtering functions by constructing function handles from nested functions. Each of these handles maintains its own internal state independent of the others.
The function makeFilter takes IIR filter coefficient vectors a and b and returns a filtering function in the form of a function handle. Each time a new input value xn is available, you can call the filtering function to get the new output value yn. Each filtering function created by makeFilter keeps its own private a and b vectors, in addition to its own private state vector, in the form of a transposed direct form II delay line:
function [filtfcn, statefcn] = makeFilter(b, a)
% FILTFCN = MAKEFILTER(B, A) creates an IIR filtering
% function and returns it in the form of a function handle,
% FILTFCN. Each time you call FILTFCN with a new filter
% input value, it computes the corresponding new filter
% output value, updating its internal state vector at the
% same time.
%
% [FILTFCN, STATEFCN] = MAKEFILTER(B, A) also returns a
% function (in the form of a function handle, STATEFCN)
% that can return the filter's internal state. The internal
% state vector is in the form of a transposed direct form
% II delay line.
% Initialize state vector. To keep this example a bit
% simpler, assume that a and b have the same length.
% Also assume that a(1) is 1.
v = zeros(size(a));
filtfcn = @iirFilter;
statefcn = @getState;
function yn = iirFilter(xn)
% Update the state vector
v(1) = v(2) + b(1) * xn;
v(2:end-1) = v(3:end) + b(2:end-1) * xn - ...
a(2:end-1) * v(1);
v(end) = b(end) * xn - a(end) * v(1);
% Output is the first element of the state vector.
yn = v(1);
end
function vOut = getState
vOut = v;
end
endThis sample session shows how makeFilter works. Make a filter that has a decaying exponential impulse response and then call it a few times in succession to see the output values change:
[filt1, state1] = makeFilter([1 0], [1 -.5]); % First input to the filter is 1. filt1(1) ans = 1 % Second input to the filter is 0. filt1(0) ans = 0.5000 filt1(0) ans = 0.2500 % Show the filter's internal state. state1() ans = 0.2500 0.1250 % Hit the filter with another impulse. filt1(1) ans = 1.1250 % How did the state change? state1() ans = 1.1250 0.5625 % Make an averaging filter. filt2 = makeFilter([1 1 1]/3, [1 0 0]); % Put a step input into filt2. filt2(1) ans = 0.3333 filt2(1) ans = 0.6667 filt2(1) ans = 1 % The two filter functions can be used independently. filt1(0) ans = 0.5625
As an extension of this example, suppose you were looking for a way to develop simulations of different filtering structures and compare them. This might be useful if you were interested in obtaining the range of values taken on by elements of the state vector, and how those values compare with a different filter structure. Here is one way you could capture the filter state at each step and save it for later analysis:
Call makeFilter with inputs v1 and v2 to construct function handles to the iirFilter and getState subfunctions:
[filtfcn, statefcn] = makeFilter(v1, v2);
Call the iirFilter and getState functions by means of their handles, passing in random values:
x = rand(1, 20);
for k = 1:20
y(k) = filtfcn(x(k));
states{k} = statefcn(); % Save the state at each step.
end
![]() | Primary M-File Functions | Subfunctions | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |