Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do nested functions work in MATLAB?

So, I'm applying for a job and need to figure out how nested functions work. To be more specific, I would like to know exactly how the following example posted by gnovice works.

The question is:

Given the following function, what will the output be when entering the code below in the command window?

function fcnHandle = counter
  value = 0;
  function currentValue = increment
    value = value+1;
    currentValue = value;
  end
  fcnHandle = @increment;
end

f1 = counter();
f2 = counter();
output = [f1() f1() f2() f1() f2()];  %# WHAT IS IT?!

I'm not applying for a job, and I'm able to figure out the answer to the question. I also find the answer from Mohsen to this question intuitive (find the size of a matrix without calling built-in functions). However, I can't help but hearing Albert Einstein's voice in my head.

enter image description here

I think the documentation was a bit messy, so I would be very happy if someone is able to explain how it works.

like image 401
Stewie Griffin Avatar asked Oct 07 '14 14:10

Stewie Griffin


2 Answers

This use of nested functions is relevant for memoization (for additional reading see: use nested functions to memoize costly functions), since it exploits parametric function handles which store the value of the parameters at creation.

There are two things you need to notice:

  1. counter() returns a function handle directly to the nested function

    f1 = counter()
    f1 = 
       @counter/increment
    
  2. The nested function will 'save' the scoped variables. Refer to functions() for details.

    s = functions(f1)
    s = 
         function: 'counter/increment'
             type: 'nested'
             file: '\\ic.ac.uk\homes\ok1011\MATLAB\counter.m'
        workspace: {[1x1 struct]}
    

    with the scoped workspace retaining:

    s.workspace{1}
    ans = 
        fcnHandle: @counter/increment
            value: 0
    

Basically, counter() initializes the value to zero, and successive calls to @counter/increment will perform value = value+1;.

Finally, @counter/increment is assigned to f1 and all f1() is doing is @counter/increment() on the previously initialized value. Initializing f2 = counter(), creates another counter with a separate saved workspace.

like image 52
Oleg Avatar answered Oct 06 '22 03:10

Oleg


Let me try....

Each time the function counter() its called creates an unique function handle. This function handle is a handle to a function called increment, that takes its own variable value, and increments its by one.

So if called twice, like in the code (f1, f2) each time will return the same function (increment) but different handles. You have the function defined TWICE. And each of them now work independently. As this specific function (increment) relies in a saved internal value for its computation, you can observe how if called as in your code sample, outputs [1 2 1 3 2].

A good way of seing the differences better is to redefine the function as:

function fcnHandle = counter(val)
  value = val;
  function currentValue = increment
    value = value+1;
    currentValue = value;
  end
  fcnHandle = @increment;
end

and calling it like:

>> f1 = counter(0);
>> f2 = counter(1000);
>> output = [f1() f1() f2() f1() f2()]  %# WHAT IS IT?

Now, you will see that the output is [1 2 1001 3 1002]

Makes more sense now?

This code is created so it exploits this attribute of function handles (its the same thing, but its copied twice).

like image 33
Ander Biguri Avatar answered Oct 06 '22 01:10

Ander Biguri