1) What does an anonymous function “capture”?
- Only the variables it actually references in its definition, not the whole workspace.
- Those variables are captured at the time the handle is created.
- For value types (e.g. numeric arrays, cell arrays, structs) this means the value is copied into the handle’s workspace at creation. Changing the original variable later does not affect the handle.
- For handle objects (e.g. graphics handles, containers.Map, user-defined handle classes), the handle reference is captured—so later changes/mutations of the object are visible through the function handle.
Example (value type):
Example (handle object):
m = containers.Map("k",1);
2) What if you edit the called M-file later?
Your anonymous function f=@()helperFunction1(a) captures a as discussed above.
The code it calls (i.e. helperFunction1) is not frozen inside f. A function handle (directly or inside an anonymous function) points to the function by path/name, not a snapshot of its code. If you edit helperFunction1.m after creating f, subsequent calls to f will use the updated code in that same file/path. (If you move/rename the file or create a higher-priority shadow on the path, you can change which code is called; otherwise, edits take effect automatically).
3) What about nested functions (closures)?
Lets try it right now:
- Nested functions share the parent workspace. The returned handle keeps that workspace alive.
- Changes to shared variables are seen by all nested-function handles, even if the change happens after the handle was created (as long as it’s the same shared variable).
- This is by-reference to the shared workspace, not a one-time copy (standard copy-on-write semantics still apply to arrays when you reassign them, but the identity of the shared variable is the same).
So, for nested functions: think “closure by reference to the shared workspace,” unlike anonymous captures of value types from the base or caller workspace.
4) Do anonymous functions always capture “everything in scope”?
No. They only capture the variables that appear in the anonymous expression (the free variables). Unused variables are not captured.
5) Should you worry about performance/memory?
Usually, no—but a few tips:
- Only referenced variables are captured. MATLAB already excludes everything else.
For large value-type variables, capture implies keeping a separate stored value with the handle. If you create many handles that each capture a large array, that’s memory you’ll retain. In those cases, consider:
- Passing the large data as an input argument instead of capturing it, or
- Capturing a handle object that references the data (if appropriate), or
- Storing large data somewhere accessible and only capturing a small key/handle.
- Call overhead of a handle/anonymous function is small and typically negligible compared to real work inside.