When calling functions which use themselves, am I bogging down the processor?

Information: Assume for some task you use the following code:
test = functionMaker(5);
disp(test(3))
243
function [outbox] = functionMaker(N)
f = @(x) 1; %% Initialize
for i = 1:N
f = @(x) f(x) * x;
end
outbox = f;
end
In the Workspace, the variable test has a Value of @(x)f(x)*x.
Question: Does this mean that MATLAB is keeping the functions open which created test? If not, then do normal methods of clearing the workspace also eliminate every instance generated of the function f?
Aside: Please note that while this particular example can be simplified to , a more complicated function might not simplify. Also, the code block didn't run in the browser, but successfully displays 243 on my local machine.

 Accepted Answer

Does this mean that MATLAB is keeping the functions open which created test?
When you create an anonymous function and the body of the function references a variable other than one of the named arguments, then a property named workspace is populated inside the anonymous function object. The workspace property is a 1 x 1 cell array that contains a scalar struct, with one field for each "captured" variable, with the field name the same as the name of the variable, and with the field value being a reference to the variable.
So the first time, i = 1, you had f = @(x) 1 and then when you have i = 2 then the anonymous function @(x) f(x) * x first binds the existing f(x) into the workspace struct . Then because of the assignment, the new anonymous function is bound as f inside the workspace of functionMaker
At this point, the workspace of functionMaker contains a variable named f which is an anonymous function object. The workspace property contains a struct with field f that points to the previous f, the @(x) 1 version. So the @(x) 1 version still has a reference to it, and so the @(x) 1 version is not deleted.
Next cycle, the @(x) f(x) * x anonymous function has previous f bound into it and so there is a retained reference to it. And it still refers to the @(x) 1 version... and so on.
When you test = functionMaker(5); what is returned is the last anonymous function -- the one that has a reference to the previous version of the anonymous function, which in turn has a reference to the one before that, and so on.
If you were to now clear test then the last reference to the most recent anonymous function would be released so the deletion process would crawl through the properties of that anonymous function and clear the properties. Which would release the struct of the top level, which would release the reference to the previous anonymous function, triggering deletion process for it, triggering release of the previous one, and so on all the way down to the @(x) 1 edition which has nothing bound into it and so the chain does not need to be released any further.
After you have assigned test = functionMaker(5) then the previous levels do not live in the workspace of functionMaker and clear functionMaker would not clear those anonymous functions. You would have to clear test (and any copies of test that you had made.)

2 Comments

Note that calling an anonymous function is slow. If you are building up a function incrementally, then it can often make sense to build it up symbolically, and then matlabFunction() to create a function handle for execution.

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!