# Closures in MATLAB

Date: 5-31 2017

Tags: matlab, programming

## Introduction

Nested functions
and anonymous functions
provide great flexibility when coding in MATLAB. They also make it possible to create
closures
(I mean the closures in computer programming, not mathematics) in MATLAB,
leading to some interesting use cases. In simple words, a closure captures a
**persistent local variable scope**, which usually occurs when your
function A returns a function B that references local variables in function A.
In MATLAB, if you write the some code similar to the code below, you create
a closure:

```
function g = scale_operator(f, scale)
% Here we assume f has a single return value, and scale is also a scalar
function y = scaled_function(varargin)
% Note that we use the local variable scale and f here, which is within
% the scope of scale_operator().
y = scale * f(varargin{:});
end
g = @scaled_function;
end
```

When you call the returned function, it will access the local variables `f`

and
`scale`

captured in the closure.

You may wonder why it bothers to write such "confusing" code to make a function return a function. Interestingly, the above code implements a simple scale operator (here I mean the operator in mathematics, not computer programming) that maps functions with their scaled versions. Take a look at the following code and you will get a better idea:

```
f = @(x) x.*x; % just a simple quadratic function
g = scale_operator(f, 2); % g(x) = 2*f(x)
h = scale_operator(g, 3); % h(x) = 3*g(x)
disp(f([1 2 3])); % [1 4 9]
disp(g([1 2 3])); % [2 8 18]
disp(h([1 2 3])); % [6 24 54]
```

Interesting? Let us continue.

## The Light Side

In addition to the above example, there are many other neat applications that
utilize closures in MATLAB. The most straightforward application is
**parameterizing functions**. Basically, you create a function that works like
a factory that creates new functions depending on the input parameters. The
example below shows a quadratic function factory. It will create a new quadratic
function with every set of new coefficients.

```
function qf = create_quadratic_function(a, b, c)
function y = quadratic_function(x)
y = a*x.^2 + b*x + c;
end
qf = @y;
end
```

If you are an one-linear, you can also define the above function using the syntax of anonymous functions:

```
create_quadratic_function = @(a,b,c) @(x) a*x.^2 + b*x + c;
```

However, when you need to perform complex operation with respect to the parameters, you may need to use the syntax of nested functions. Use the syntax of anonymous functions only when it is clear and concise.

Now we can create new quadratic functions and use them just as normal MATLAB functions:

```
x = linspace(-2, 2, 100);
q1 = create_quadratic_function(1, 1, 1);
q2 = create_quadratic_function(1, -1, 1);
plot(x, q1(x), x, q2(x));
```

Running the code above and you show get the following plot:

Another interesting use case of closures arises when you want your function to
**cache the results from complex computations**, and you
**do not want to pollute the global workspace**. Consider the following
function that "solves the ultimate question":

```
function get_answer = create_ultimate_solver()
solved = false;
cached_answer = [];
function answer = solve()
if ~solved
% assuming it will take a long time to obtain this answer
cached_answer = 42;
solved = true;
disp('Solved! The answer is cached.');
else
disp('Already solved! Using the cached answer.');
end
answer = cached_answer;
end
get_answer = @solve;
end
```

When you evaluate the returned `get_answer()`

function multiple times, it will
not repeat complex computations multiple times. It will only perform
the complex computations the first time you call it, and use cached results
later on, as shown below:

```
get_answer = create_ultimate_solver();
answer1 = get_answer(); % 42, 'Solved! The answer is cached.'
answer2 = get_answer(); % 42, 'Already solved! Using the cached answer.'
answer2 = get_answer(); % 42, 'Already solved! Using the cached answer.'
```

With closures, it is also possible to **mimic an object instance** using
structs. Note that this trick does not replace the OOP programming in MATLAB,
but the resulting struct will have field that looks like methods in OOP
programming.

The idea is quite simple. We utilize closures to store private local variables. We use nested functions to manipulate these variables and connect them with the outside. We then use a MATLAB struct to store handles to these nested functions, so the struct will look like a object instance. Here is an example function that creates a counter:

```
function ctr = create_counter(n)
if nargin < 1
n = 0;
end
function increase()
n = n + 1;
end
function decrease()
n = n - 1;
end
function reset()
n = 0;
end
function set_count(m)
n = m;
end
function x = get_count()
x = n;
end
ctr.increase = @increase;
ctr.decrease = @decrease;
ctr.reset = @reset;
ctr.set_count = @set_count;
ctr.get_count = @get_count;
end
```

The returned counter struct will have five "methods". We can increase/decrease
the count by calling `ctr.increase()`

/`ctr.decrease()`

, reset the counter
by calling `ctr.reset()`

, get/set the current count by calling `ctr.get_count()`

/`ctr.set_count()`

, as shown below:

```
ctr1 = create_counter();
ctr2 = create_counter(10);
disp(ctr1.get_count()); % 0
disp(ctr2.get_count()); % 10
ctr1.increase();
ctr2.decrease();
disp(ctr1.get_count()); % 1
disp(ctr2.get_count()); % 9
```

Here each created counter has it own closure to store the count variable, and they are independent of each other.

Similarly, we can create a **stateful** sine wave generator as follows, which
stores the current phase in the corresponding closure:

```
function wg = create_sine_wave_generator(f, fs)
% Here f is the frequency of the sine wave, and fs is the sampling frequency.
phase = 0;
function y = next_samples(n)
tmp = 2 * pi * f * (0:n - 1) / fs + phase;
y = sin(tmp);
phase = phase + 2 * pi * f * n / fs;
end
function reset()
phase = 0;
end
wg.next_samples = @next_samples;
wg.reset = @reset;
end
```

Now we can create a new sine wave generator and generate some samples as follows:

```
wg = create_sine_wave_generator(1, 50);
y1 = wg.next_samples(20); % get the next 20 samples
y2 = wg.next_samples(20); % get the next 20 samples
wg.reset(); % reset
y3 = wg.next_samples(20); % get the next 20 samples
stem(1:20, y1); hold on;
stem(21:40, y2); hold on;
stem(41:60, y3); hold off;
```

Running the above code you will get the plot above. It can be observed that the new sine wave generator is indeed stateful.

## The Dark Side

While closures are powerful, we need to be cautious when using them. Here are three things to remember when your MATLAB code involves closures:

Closures may cause memory leaks. Things get worse when you define a function that returns a function that returns a function that ... Additionally, because the local variables captured in closures are not visible in the global workspace. You cannot not use

`clear varname`

to clear them directly, and you may forget to clear them. To clear them, you need to clear the returned function handle (e.g.,`g`

and`h`

in the example at the very beginning) associated with their closure.There is a

**crucial difference**between anonymous functions and nested functions when capturing the local variables:- When an anonymous function is created, the
**immediate values**of the referenced local variables will be captured. Hence if any changes to the referenced local variables**made after the creation of this anonymous function**will not affect this anonymous function. - When a nested function is created, the
**immediate values**of the referenced local variables**will not be captured**. When the nested function is called, it will use the**current values**of the referenced local variables.

To get a better understanding, consider the following two functions:

`function [f1, f2] = create_functions_anonymous() ii = 1; f1 = @(x) x * ii; ii = 2; f2 = @(x) x * ii; end function [f1, f2] = create_functions_nested() ii = 1; function y = function_1(x) y = x * ii; end f1 = @function_1; ii = 2; function y = function_2(x) y = x * ii; end f2 = @function_2; end`

If you run the code below, you will observe the difference.

`[f1, f2] = create_functions_anonymous(); disp(f1(9)); % 9 disp(f2(9)); % 18 [f1, f2] = create_functions_nested(); disp(f1(9)); % 18 disp(f2(9)); % 18`

- When an anonymous function is created, the
When using

`parfor`

or similar parallel processing functions, local variables captured in closures will be**copied to each worker**, instead of being shared among all the workers. This will lead to unexpected results. Consider the following code:`results = zeros(8, 4); ctr = create_counter(); % see the example above on how to create a counter parfor ii = 1:8 for kk = 1:4 ctr.increase(); results(ii,kk) = ctr.get_count(); end end disp(results);`

If you run the above code with 4 MATLAB worker, you will get very confusing results which look like this:

`5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 9 10 11 12`

Actually, you will get difference results each time you run the above code. This occurred because

`ctr`

and its closure will be copied to the 4 workers, so each work will have a counter that is independent of the counters possessed by other workers. To make matters worse, there is no guarantee how MATLAB distributes the tasks among the workers. Hence the results will be different each time.

## Summary

In summary, there are many neat trick you can do with closures in MATLAB, such as defining operators, parameterizing functions, cache local results, mimic object instances, etc. However, you must be careful when using them to avoid memory leaks and unexpected results. If you are interested, you may also check out functional programming.