Nested Functions (GNU Octave (version 11.1.0))

#### 11.10.4 Nested Functions ¶

Nested functions are similar to subfunctions in that only the main function is visible outside the file. However, they also allow for child functions to access the local variables in their parent function. This shared access mimics using a global variable to share information — but a global variable which is not visible to the rest of Octave. As a programming strategy, sharing data this way can create code which is difficult to maintain. It is recommended to use subfunctions in place of nested functions when possible.

As a simple example, consider a parent function `foo`, that calls a nested child function `bar`, with a shared variable x.

    function y = foo ()
      x = 10;
      bar ();
      y = x;

      function bar ()
        x = 20;
      endfunction
    endfunction

    foo ()
     ⇒  20

Notice that there is no special syntax for sharing x. This can lead to problems with accidental variable sharing between a parent function and its child. While normally variables are inherited, child function parameters and return values are local to the child function.

Now consider the function `foobar` that uses variables x and y. `foobar` calls a nested function `foo` which takes x as a parameter and returns y. `foo` then calls `bat` which does some computation.

    function z = foobar ()
      x = 0;
      y = 0;
      z = foo (5);
      z += x + y;

      function y = foo (x)
        y = x + bat ();

        function z = bat ()
          z = x;
        endfunction
      endfunction
    endfunction

    foobar ()
        ⇒  10

It is important to note that the x and y in `foobar` remain zero, as in `foo` they are a return value and parameter respectively. The x in `bat` refers to the x in `foo`.

Variable inheritance leads to a problem for `eval` and scripts. If a new variable is created in a parent function, it is not clear what should happen in nested child functions. For example, consider a parent function `foo` with a nested child function `bar`:

    function y = foo (to_eval)
      bar ();
      eval (to_eval);

      function bar ()
        eval ("x = 100;");
        eval ("y = x;");
      endfunction
    endfunction

    foo ("x = 5;")
        ⇒  error: can not add variable "x" to a static workspace

    foo ("y = 10;")
        ⇒  10

    foo ("")
        ⇒  100

The parent function `foo` is unable to create a new variable x, but the child function `bar` was successful. Furthermore, even in an `eval` statement y in `bar` is the same y as in its parent function `foo`. The use of `eval` in conjunction with nested functions is best avoided.

As with subfunctions, only the first nested function in a file may be called from the outside. Inside a function the rules are more complicated. In general a nested function may call:

0. Globally visible functions
1. Any function that the nested function’s parent can call
2. Sibling functions (functions that have the same parents)
3. Direct children

As a complex example consider a parent function `ex_top` with two child functions, `ex_a` and `ex_b`. In addition, `ex_a` has two more child functions, `ex_aa` and `ex_ab`. For example:

    function ex_top ()
      ## Can call: ex_top, ex_a, and ex_b
      ## Can NOT call: ex_aa and ex_ab

      function ex_a ()
        ## Can call everything

        function ex_aa ()
          ## Can call everything
        endfunction

        function ex_ab ()
          ## Can call everything
        endfunction
      endfunction

      function ex_b ()
        ## Can call: ex_top, ex_a, and ex_b
        ## Can NOT call: ex_aa and ex_ab
      endfunction
    endfunction